Aurelia привязывает JSON к массиву компонентов с сохранением свойств объекта по умолчанию

#json #typescript #aurelia

#json #typescript #aurelia

Вопрос:

Я пытаюсь сделать следующее:

 <my-component myobjarray.bind="[{a: 'ID'}, {b: 2}]"></my-component>
  

 @customElement('my-component') 
export class MyComponent
{    
    @bindable myobjectarray: MyObject[] = [];
}
  

 @inject(MyComponent)
@customElement('my-object') 
export class MyObject
{    
    constructor(component: MyComponent) {
    }
    @bindable a:string = 'Hello';
    @bindable b:number = 1;
}
  

Проблема заключается в том, что MyComponent.myobjectarray привязывает myobjectarray к следующим значениям, потому что я только что отправил обычный объект JSON, но я хочу, чтобы он имел тип MyObject, фактически не указывая его как таковой, когда я передаю его в my-component:

 [0] a = "ID", b????
[1] a????, b = 2
  

Я бы хотел, чтобы он восстановил объект при привязке, чтобы он имел значения по умолчанию и выглядел следующим образом: (На самом деле типы MyObject)

 [0] a = "ID", b = 1 (default value)
[1] a = "Hello" (default value), b = 2
  

ПРИ желании было бы нормально, если бы я сам выполнил сопоставление в bind или что-то подобное, но я не могу создать новый экземпляр MyObject (this) в MyComponent, но Aurelia выдает ошибки и не позволяет мне вводить MyComponent в MyObject. (Не уверен, как это сделать, но я хотел бы знать)

Комментарии:

1. JavaScript не является типизированным языком. Невозможно определить тип при передаче в JSON. В любом случае привязка к JSON не является хорошей идеей, и когда вы приводите его в качестве примера, трудно понять, к чему вы клоните с примером.

2. Я понимаю, что JS не напечатан. Привязка к свойству, содержащему данные JSON, не является хорошей идеей? Чрезвычайно часто веб-служба возвращает данные JSON, где данные должны быть привязаны к элементу управления и отображаться в виде списка элементов в выпадающем списке или списка строк в таблице данных. Вы можете рассматривать «MyComponent» как выпадающий список, а «MyObject» — как выпадающий элемент для обсуждения. Основываясь на моем ответе, я хочу либо жестко закодировать элементы в раскрывающемся списке с вложенностью my-component / my-object, ЛИБО получить элементы из WS (данные JSON), сохраняя свойство MyObject по умолчанию !указано.

3. > Очень часто веб-служба возвращает данные JSON Да. Но затем вы анализируете его с помощью JSON.parse , и это объект. Нет смысла получать строку JSON из веб-службы и привязывать ее к вашему представлению без ее синтаксического анализа. И поэтому этот пример трудно понять.

4. Очевидно, что вы зациклены на том, почему я передаю JSON в виде строки, но это не более чем ярлык, позволяющий сократить вопрос. Даже в этом примере использование .bind там для этой «строки» дает совершенно допустимый массив объектов JSON по времени, когда он привязан / попадает в myobjectarrayChanged(значение) в MyComponent view-model. Без .bind да, это была бы бесполезная строка. Я мог бы очень хорошо включить полный сервис и тому подобное, но это не имеет отношения к вопросу. Уже выяснил способы сделать то, что я хотел, так что в любом случае спасибо. Лучший способ сделать это? Понятия не имею.

5. Если вы передаете JSON, это, очевидно, будет JSON. Если вы передаете объект, этот объект может (должен) уже быть проанализирован как MyObject.

Ответ №1:

Я выяснил, как сделать это «необязательным» способом, которым я хотел, чтобы это было сделано, что является смехотворным объемом работы, чтобы заставить что-то подобное работать. Было бы лучше, если бы bind мог просто автоматически добавлять подкомпоненты (не вводя их в шаблон), когда они не являются полными объектами JSON типа подкомпонента. Я все еще открыт для лучшего / правильного способа сделать это, но это мое текущее решение:

В MyComponent добавить:

     constructor(private bindingEngine:BindingEngine, private viewCompiler:ViewCompiler, private viewSlot:ViewSlot, private container:Container, private resources:ViewResources){
    }

    myobjectarrayChanged(value) {        
        this.myobjectarray = [];
        var item:any;
        var sItems = '<template>';
        for(let item of value){
            sItems  = `${'<my-object'}
                ${item.hasOwnProperty('a') ? ' a="'   item.a   '"' : ''}
                ${item.hasOwnProperty('b') ? ' b="'   item.b   '"' : ''}
                ${'></my-object>'}`;
        }
        sItems  = '<template>';

        var viewFactory =  this.viewCompiler.compile(sItems, this.resources);
        var bindingContext = null; 
        var view = viewFactory.create(this.container, bindingContext);
        this.viewSlot.add(view);
        this.viewSlot.attached();
    }
  

И в MyObject добавьте это в конструктор:

 component.myobjectarray.push(this);
  

Это позволяет указать свой компонент следующим образом:

 <my-component myobjarray.bind="[{a: 'ID'}, {b: 2}]"></my-component>
  

или

 <my-component>
    <my-object a='ID'></my-object>
    <my-object b='2'></my-object>
</my-component>
  

Это то, что я пытался реализовать.