Nativescript自定义控件 - 更新依赖项属性

时间:2016-03-15 11:04:38

标签: data-binding typescript nativescript

我正在创建一个自定义组件,它是一个按钮列表。

当用户点击一个按钮时,我改变了它的css类,然后我想将它添加到一个自定义的" selectedItems"在我的ViewModel中检索它的属性。

当我推动" selectedItems"数组属性,没有引发任何事件,我也无法获取信息。 此外,我试图重新设置整个阵列但不是更好。

我不知道如何实现这一目标。

以下是我的组件的代码:

import {WrapLayout} from "ui/layouts/wrap-layout";
import {EventData} from "data/observable";
import {ValueButton} from "./value-button";
import dependencyObservableModule = require("ui/core/dependency-observable");

export class ValuesSelector extends WrapLayout {
    public static itemsProperty = new dependencyObservableModule.Property(
        "items",
        "ValuesSelector",
        new dependencyObservableModule.PropertyMetadata(
            [],
            dependencyObservableModule.PropertyMetadataSettings.None,
            function(data: dependencyObservableModule.PropertyChangeData) {
                if (data.newValue) {
                    let instance = <ValuesSelector>data.object;
                    instance.items = data.newValue;
                }
            }));

    public static deleteOnClickProperty = new dependencyObservableModule.Property(
        "deleteOnClick",
        "ValuesSelector",
        new dependencyObservableModule.PropertyMetadata(
            false,
            dependencyObservableModule.PropertyMetadataSettings.None));

    public static selectedItemsProperty = new dependencyObservableModule.Property(
        "selectedItems",
        "ValuesSelector",
        new dependencyObservableModule.PropertyMetadata(
            [],
            dependencyObservableModule.PropertyMetadataSettings.None));

    public static singleSelectionProperty = new dependencyObservableModule.Property(
        "singleSelection",
        "ValuesSelector",
        new dependencyObservableModule.PropertyMetadata(
            false,
            dependencyObservableModule.PropertyMetadataSettings.None));

    public get selectedItems() {
        return this._getValue(ValuesSelector.selectedItemsProperty);
    }
    public set selectedItems(value: any[]) {
        this._setValue(ValuesSelector.selectedItemsProperty, value);
    }

    public get deleteOnClick() {
        return this._getValue(ValuesSelector.deleteOnClickProperty);
    }
    public set deleteOnClick(value: boolean) {
        this._setValue(ValuesSelector.deleteOnClickProperty, value);
    }

    public get singleSelection() {
        return this._getValue(ValuesSelector.singleSelectionProperty);
    }
    public set singleSelection(value: boolean) {
        this._setValue(ValuesSelector.singleSelectionProperty, value);
    }

    public get items() {
        return this._getValue(ValuesSelector.itemsProperty);
    }
    public set items(value: any) {
        this._setValue(ValuesSelector.itemsProperty, value);
        this.createUI();
    }

    private _buttons: ValueButton[];

    constructor() {
        super();
        this.orientation = "horizontal";
        this._buttons = [];
    }

    private createUI() {
        this.removeChildren();
        let itemsLength = this.items.length;

        for (let i = 0; i < itemsLength; i++) {
            let itemButton = new ValueButton();
            itemButton.text = this.items[i].label;
            itemButton.value = this.items[i];
            itemButton.className = "values-selector-item";

            if (this.deleteOnClick) {
                itemButton.className = "values-selector-selected-item";
            }

            itemButton.on(ValueButton.tapEvent, (data: EventData) => {
                let clickedButton = <ValueButton>data.object;

                if (this.deleteOnClick) {
                    let itemIndex = this.items.indexOf(clickedButton.value);
                    if (itemIndex > -1) {
                        let newSelectedItems = this.items;
                        newSelectedItems.splice(itemIndex, 1);
                        this.items = newSelectedItems;
                    }
                    return;
                }

                let internalSelectedItems = this.selectedItems;

                if (clickedButton.className === "values-selector-item") {
                    if (this.singleSelection && this.selectedItems.length > 0) {
                        internalSelectedItems = [];

                        for (let i = 0; i < this._buttons.length; i++) {
                            this._buttons[i].className = "values-selector-item";
                        }
                    }
                    internalSelectedItems.push(clickedButton.value);

                    clickedButton.className = "values-selector-selected-item";
                } else {
                    let itemIndex = internalSelectedItems.indexOf(clickedButton.value);
                    if (itemIndex > -1) {
                        internalSelectedItems.splice(itemIndex, 1);
                    }

                    clickedButton.className = "values-selector-item";
                }

                this.selectedItems = internalSelectedItems;
            }, this);

            this._buttons.push(itemButton);
            this.addChild(itemButton);
        }
    }
}
你能帮帮我吗? 感谢

1 个答案:

答案 0 :(得分:1)

好的,我通过数据绑定我的属性犯了一个错误。

事实上,在XML中我使用这样的组件:

<vs:ValuesSelector items="{{ criterias }}" selectedItems="{{ myObject.selectedCriterias }}" />

但是在ViewModel中,我从未初始化selectedCriterias属性,因为我认为组件中指定的默认值[]会创建它。

所以在ViewModel中,这是修复:

  • this.myObject = {     id:0 };

  • this.myObject = {     id:0,     selectedCriterias:[] };