Javascript 在observableArray中设置元素动画

Javascript 在observableArray中设置元素动画,javascript,knockout.js,Javascript,Knockout.js,我想从一个可观察的数组中设置一个元素的动画 我不是在observableArray中添加或删除项目 考虑到下面的JSFIDLE,我想调用animateFirstElement函数并突出显示行星“Mercury” 我可以很容易地得到这个项目。但我不知道如何获取它对应的HTML元素: this.animateFirstElement = function() { alert(this.planets()[0].name); }; 您可以这样做: 换行: <div data-bind

我想从一个可观察的数组中设置一个元素的动画

我不是在observableArray中添加或删除项目

考虑到下面的JSFIDLE,我想调用animateFirstElement函数并突出显示行星“Mercury”

我可以很容易地得到这个项目。但我不知道如何获取它对应的HTML元素:

this.animateFirstElement = function() {
    alert(this.planets()[0].name);
}; 
您可以这样做: 换行:

<div data-bind='attr: { "class": name + "_" + type }, text: name'> </div>
this.animateFirstElement = function() {
    $("." + this.planets()[0].name + "_" + this.planets()[0].type).toggle();
};

this.animateFirstElement=函数(){
$(“+”this.planers()[0]。名称+“”+this.planers()[0]。键入)。切换();
};

我支持@CrimsonChris在评论中所说的话,尽管这两种方式都相当简单。默认情况下,Knockout将参数
数据、事件
传递给视图上的任何绑定。例如,如果您想在用户单击某个行星时高亮显示该行星,您可以执行以下操作:

<div data-bind="attr: { 'class': 'planet ' + type }, 
                text: name, 
                click: highlightElement"> </div>
如果要从父上下文触发操作,可以将一个好的ol'
id
属性粘贴到容器中,例如
planet list
,并使用jQuery在敲除之外设置添加/删除动画,例如:

this.removeFirstElement = function() {
    var target = document.getElementById('planet-list'),
        planet = target.children[0];
    $(planet).slideUp(400,function() { self.planets.shift(); });
};
您也可以在knockout中执行此操作,例如,通过构建自定义绑定,或者您可以使用
planetsToShow.subscribe
在数组变小/变大时相应地设置动画。请注意,在视图中,您可以完美地将
$element
传递给函数或
$index
(如下面的测试中所示)


我已经对你的小提琴做了一些修改,请查看:

关键是不能对抗击倒。您的viewmodel永远不需要知道用于呈现它的HTML元素

如果要影响项目的可见性,请在viewmodel上引入
visible
属性,并使视图对该属性中的更改作出反应。如有必要,创建处理动画本身的自定义绑定-我已经在下面创建了
fadeVisible
slideVisible
绑定

下面使用一个单独的
Planet
viewmodel和对
typeToShow
属性的订阅

功能行星(数据){
var self=这个;
self.name=data.name;
self.type=data.type;
自可见=可观察(真);
}
Planet.create=函数(数据){
返回新行星(数据);
};
功能(数据){
var self=这个;
self.planets=ko.observearray(ko.utils.arrayMap(data.planets,Planet.create));
self.typeToShow=ko.可观察(“全部”);
self.displayAdvancedOptions=ko.可观察(true);
self.addPlanet=函数(名称、类型){
自我。行星。推(新行星)({
名称:名称| |“新行星”,
类型:类型| |“岩石”
}));
};
self.typeToShow.subscribe(函数(类型)){
ko.utils.arrayForEach(self.planets(),function(planet){
planet.visible(类型==“所有”| | ko.unwrap(planet.type)==类型);
});
});
}
ko.bindingHandlers.fadeVisible={
init:函数(元素、值访问器){
var value=valueAccessor(),
可见=ko.展开(值);
$(元素).切换(可见);
},
更新:函数(元素、值访问器){
var value=valueAccessor(),
可见=ko.展开(值);
$(元素)[可见?“淡出”:“淡出”]();
}
};
ko.bindingHandlers.slidevible={
init:函数(元素、值访问器){
var value=valueAccessor(),
可见=ko.展开(值);
$(元素).切换(可见);
},
更新:函数(元素、值访问器){
var value=valueAccessor(),
可见=ko.展开(值);
$(元素)[可见?“slideDown”:“slideUp”]();
}
};
ko.应用绑定(新行星)({
行星:[
{名称:“水星”,类型:“岩石”},
{名称:“维纳斯”,类型:“岩石”},
{名称:“地球”,类型:“岩石”},
{名称:“火星”,类型:“岩石”},
{名称:“Jupiter”,键入:“Gasgantian”},
{名称:“土星”,类型:“气体巨人”},
{名称:“天王星”,类型:“气体巨人”},
{名称:“海王星”,类型:“气体巨星”},
{名称:“冥王星”,类型:“岩石”}
]
}));
body{font-family:arial;字体大小:14px;}
.liveExample{填充:1em;背景色:#eeedd;边框:1px实心#CCC;最大宽度:655px;}
.liveExample输入{font-family:Arial;}
.liveExample b{font-weight:bold;}
.liveExample p{页边距顶部:0.9em;页边距底部:0.9em;}
.liveExample选择[多个]{宽度:100%;高度:8em;}
.liveExample h2{页边空白顶部:0.4em;}
.planet{背景色:AAEECC;填充:0.25em;边框:1px纯银;边距底部:0.5em;字体大小:0.75em;}
.planet.rock{背景色:#EECCAA;}
.liveExample输入{margin:0 0.3em 0 1em;}
li{列表样式类型:光盘;左边距:20px;}

行星

展示: 全部的 岩石行星 气态巨行星


直接访问和操作HTML元素是Knockout试图阻止您执行的操作。视图应该依赖于视图模型,而不是相反。考虑使用绑定绑定到视图模型中的属性来触发动画。这里有一个类似的问题,其中有一个很好的答案。当我点击一个按钮时,你能解释一下如何给第一颗行星设置动画吗?这就是最初的问题:)请看我答案的最后一句。那就明白我的答案了。然后你会明白的。对不起,我真的没明白。也许我错过了您在这里所做的:$(元素)[可见?“fadeIn”:“fadeOut”]();也许吧,但这是解决方案的核心所在。再读一遍我答案第二段的第一句话。(我不会告诉你该怎么做,我希望你自己意识到这一点。这样学习效果会更高。)(
$(元素)[可见?“fadeIn”:“fadeOut”]();
计算为
$(元素)。fadeIn
this.removeFirstElement = function() {
    var target = document.getElementById('planet-list'),
        planet = target.children[0];
    $(planet).slideUp(400,function() { self.planets.shift(); });
};