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

Nativescript custom control - Update Dependency Property

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

当用户点击一个按钮时,我更改它的 css class 然后我想将它添加到自定义 "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);
        }
    }
}

你能帮帮我吗? 谢谢

好吧,我在数据绑定 属性 时犯了一个错误。

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

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

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

所以在 ViewModel 中,这里是修复方法:

  • 之前

    this.myObject = { 编号:0 };

  • 之后

    this.myObject = { 编号:0, selectedCriterias: [] };