所以现在我有一个显示一些值的表,我有一个冲突指标。当用户点击指示符时,会出现一个新的div,其中包含一些动画以列出所有冲突。
这是我的HTML:
<span data-bind="if: hasConflict, click: $parent.selectProperty" class="conflictWarn"><i style="color: darkorange; cursor:pointer;" class="icon-warning-sign"></i></span>
数据可能如下所示:
{
name:Property 1,
id: 1,
hasConflicts: no,
name:Property 2,
id: 2,
hasConflicts: yes,
conflicts: {
name: conflict1,
name: conflict2
}
name:Property 3,
id: 3,
hasConflicts: yes,
conflicts: {
name: conflicta,
name: conflictb
}
所以第一个表格看起来像这样:
Property 1
Property 2 !
Property 3 !
哪里!是一个冲突指标。点击!将显示冲突div并显示conflict1和conflict2或conflicta和conflictb,具体取决于被点击的内容。
这是我们正在使用的模型。由于信号器的属性映射,它有点复杂。 “selectProperty”和“selectedProperty”是我们说出哪一个显示冲突的方式,但我不相信这是最好的方法。
function ItemViewModel() {
var self = this;
self.name = ko.observable("");
self.itemType = ko.observable("");
self.propertiesArray = ko.observableArray([]);
self.properties = ko.mapping.fromJS({});
self.selectedPropertyName = ko.observable("");
self.getItem = function (name) {
$.connection.mainHub.server.getItem(name).then(function (item) {
ko.mapping.fromJS(item.properties, self.properties);
self.propertiesArray(item.propertiesArray);
self.itemType(item.itemType.name);
self.name(item.name);
});
self.selectProperty = function (a, b) {
self.selectedPropertyName(a);
};
};
}
最初的click事件直接调用了一个完成所有动画的javascript函数,但是我的同事认为这可能违反了在MVVM中分离数据和视图模型的最佳实践。可以?我们应该让它调用“selectProperty”的viewmodel函数,它允许我们为“冲突弹出”div传递上下文吗?如果是这样,我是否只是调用javascript函数从selectProperty函数中执行动画?
P.S。我已经编辑了大约800次,所以如果无法遵循,我会道歉。
更新我现在有绑定工作,所以我真的只想知道UI动画和Knockout的最佳做法。从javascript函数更改viewmodel或从viewmodel函数调用javascript函数?
答案 0 :(得分:1)
在我看来,关于UI动画,最佳实践是实现自定义绑定。这种方式代码被封装,很容易找到它的使用位置。在淘汰赛网站上查看Animated transitions example。
答案 1 :(得分:0)
我要用一点来扩展Thomas的答案,当你想要动画渲染/取消渲染'if'或'with'绑定时,自定义绑定不起作用。试图在“if”或“with”的同时运行的动画绑定将无法在另一个绑定改变DOM之前完成动画,可能会从页面中删除动画元素。在事件完成之前,无法推迟绑定处理。
对于这些情况,动画应该通过'foreach'绑定的'afterAdd'和'beforeRemove'回调实现,当需要动画从页面添加和删除的元素时。 'if'和'with'绑定可以用很少的努力重写为'foreach',因为'foreach'可以采用单个参数而不是列表。我真的希望动画教程能够扩展到包含这种解决方法。