Knockout自定义组件未更新

时间:2017-04-04 13:39:05

标签: knockout.js

我有一个自定义组件,它使用函数传递参数。在这种情况下,可观察值($ data)不会改变,但该函数使用另一个observable(正在改变)和一个哈希表(它正在改变,但不能被观察到)。

使用此语法时显示更新:

        <span style="width: 50px; position: absolute; left: 1100px;text-align:center" data-bind="component: {name: ''rotate'', params: {values: Helper.GetWeatherByFlight($data, ''Hi'')}}"></span>

但是当我使用这种语法时它不会更新:

        <rotate style="width: 50px; position: absolute; left: 1100px;text-align:center" params="{values: Helper.GetWeatherByFlight($data, ''Hi'')}"></rotate>

这是组件:

ko.components.register('rotate', {
    viewModel: function (params) {
        var values = [];
        var inputValues = ko.isObservable(params.values) ? params.values() : params.values;
        var length = inputValues.length;
        this.MyClass = length > 1 ? "fade-effect" : "";
        if (length >= 1) {
            var index = m_counter % length;
            $.each(inputValues, function (i, value) {
                var opacity = (index == i) ? 1 : 0;
                values.push({ value: value, opacity: opacity });
            });
        }
        this.values = values;
    },
    template: '<span style="position:relative;" data-bind="foreach: values, attr: { class: MyClass }">\
                    <span style="left:0px;top:0px;position:absolute;width:100%;height:100%;" data-bind="text: Helper.GetValue(value, $element), style: {opacity: opacity}"></span>\
                </span>'
});

我更喜欢能够使用第二种格式,但现在我仍然坚持使用第一种格式。是否可以在组件或组件调用方式中更改某些内容,以便使两种格式都正确更新?我意识到这是一种有点不同寻常的用法。

1 个答案:

答案 0 :(得分:1)

组件在第一种情况下刷新的唯一原因是组件绑定正在查找更改,然后在检测到任何组件时重新初始化整个组件。

旋转组件本身并不会对您的参数进行处理,因为它们可以观察到它只会查看未展开的值,因此无需告诉它刷新它的观点。您需要重写组件视图模型以使用observable和计算属性,以便它可以对数据中的更改做出反应。

这样的事情:

viewModel: function (params) {
    var self = this;
    this.inputValues = params.values; //preserve the observable instead of unwrapping its values
    this.MyClass = ko.observable("");

    //values is a computed property so that it updates when the dependent observable (inputValues) is modified.
    this.values = ko.computed(function(){
        var values = [];
        //use ko.unwrap to safely handle either case of inputValues being an observable or non-observable.
        var length = ko.unwrap(self.inputValues).length;
        self.MyClass(length > 1 ? "fade-effect" : "");
        if (length >= 1) {
            var index = m_counter % length;
            $.each(ko.unwrap(self.inputValues), function (i, value) {
                var opacity = (index == i) ? 1 : 0;
                values.push({ value: value, opacity: opacity });
            });
        }
        return values;
    });
},