2016-09-06 69 views
0

场景Knockout.js |可观察到的阵列,只有当最后一个元件改变

我有多个输入字段触发器。这些字段不允许为空。如果任何字段为空,我想显示某种错误消息。


问题

我处理的问题是,我有一个观察的阵列通过淘汰赛的foreach的观点填充一些投入。

一切加载,显示器,并保存正确,但是,我的验证(这是一个计算)仅当在可观察到的变化阵列的最后一个元素,而不是当任何其它要素的改变调用。

我发现This SO Question,但是OP的问题在于他/她没有作为可观测值的值,这不是我的问题,因为我的值被封装为可观察值。


守则

Here's a fiddle

下面的代码:

查看

<div data-bind="with: itemsModel"> 
    <label data-bind="text: validMessage">Totally valid</label> 
    <div data-bind="foreach: items"> 
    <div> 
     <label>Item: </label> 
     <input type="text " data-bind="value: name " /> 
    </div> 
    </div> 
</div> 

确定JS

function ItemModel(item) { 
    self = this; 
    self.item = item; 

    self.name = ko.observable(item.name); 

    self.isValid = ko.computed(function() { 
    return self.name() && self.name().length <= 256; 
    }); 
} 

function ItemsModel(itemsModel) { 
    var self = this; 
    self.itemsModel = itemsModel; 

    self.items = ko.observableArray([ 
    new ItemModel(itemsModel.items[0]), 
    new ItemModel(itemsModel.items[1]), 
    new ItemModel(itemsModel.items[2]) 
    ]); 

    // This is only getting called when the last element in self.items changes 
    self.isValid = ko.computed(function() { 
    var isValid = true; 

    for (i = 0; i < 3; i++) { 
     isValid = isValid && self.items()[i].isValid(); 
    } 

    return isValid; 
    }); 

    self.validMessage = ko.computed(function() { 
    if (self.isValid()) { 
     return "Totally Valid"; 
    } 

    return "Totally NOT Valid"; 
    }); 
} 

function ViewModel(data) { 
    var self = this; 
    self.data = data; 

    self.itemsModel = ko.observable(new ItemsModel(data.itemsModel)); 
} 

var modelData = { 
    itemsModel: { 
    items: [{ 
     name: "Item One" 
    }, { 
     name: "Item Two" 
    }, { 
     name: "Item Three" 
    }] 
    } 
}; 

ko.applyBindings(new ViewModel(modelData)); 

回答

2

你不声明你的第一个self在本地,所以它是全球性的。

function ItemModel(item) { 
    self = this; 

应该

function ItemModel(item) { 
    var self = this; 
+0

OMG ...你是个天才!我不能相信我错过了这一点,但我想这是看着太多淘汰赛哈哈。如果我能给你一个饼干,我会,但我想接受的答案将不得不做。 –

1

淘汰赛的方式,当一个计算需要更新是有点棘手,你需要至少执行一次观察到的每一个,让他们注册。

尝试类似这样的东西。

self.isValid = ko.computed(function() { 
    var isValid = true; 

    for (i = 0; i < 3; i++) { 
     //if isValid is false second part will not executed 
     //isValid = isValid && self.items()[i].isValid(); 

     isValid = self.items()[i].isValid() && idValid; 
    } 

    return isValid; 
    }); 

我这里有一个类似的案件https://stackoverflow.com/a/38131131/2233835

希望它能帮助!

+0

虽然这不是我的问题的原因,这是一个非常正确的观点。我会为你提供一个好点的优点。 –