Knockout js $ root $ parent关键字

时间:2015-05-15 09:39:40

标签: knockout.js

我正在学习Knockout js。所以从各种来源阅读许多文章和代码。 我只是用Knockout js获得了一个小代码。我很难理解该代码中的一些区域。我将重点介绍一些,请帮助我理解。

这是完整的代码

HTML

<ul data-bind="foreach: {data: links, afterAdd: $root.fadeIn, afterRemove: $root.fadeOut}">
    <li>
        <select>
            <option>Homepege</option>
            <option>Facebook</option>
        </select>
        <input type="text" />
        <button class="close" data-bind="click: $root.removeLink">&times;</button>
    </li>
</ul>
<a href="#" data-bind="click: addLink">Add Link</a>

knockoutjs

function Link(id, url) {
    var self = this;
    self.id = id;
    self.url = url;
}

function VenueCreateViewModel() {
    var self = this;
    self.links = ko.observableArray([new Link("", "")]);
    //self.linksList = ko.observableArray(['Homepage11','Facebook']);
    self.removeLink = function (link) {
        self.links.remove(link)
    }
    self.addLink = function () {
        self.links.push(new Link("", ""));
    }

    self.fadeIn = function (element, index, data) {
        //$(element).fadeIn();
        $(element).filter("li").delay(1000).fadeIn(1000);
    }
    self.fadeOut = function (element, index, data) {
        $(element).filter("li").delay(1000).fadeOut(1000);
    }
}
ko.applyBindings(new VenueCreateViewModel());

1) 请参阅此代码data-bind="foreach: {data: links, afterAdd: $root.fadeIn, afterRemove: $root.fadeOut}"

为什么需要用$ root关键字指定函数名?

我以这种方式data-bind="foreach: {data : rows, beforeRemove : ElementFadeOut, afterAdd:ElementFadeIn}"绑定函数名称并且它有效。 请告诉我何时引用或使用$root keyword指定函数名称?

2)我有一段时间看到人们使用$ parent关键字。那么告诉我$root & $parent keyword之间有什么区别?

3)看到此代码self.links = ko.observableArray([new Link("", "")]); 为什么他们推送link object into observable Array我们可以简单地推送任何string into links observable Array

4)他们使用fadeIn & fadeOut $(element).filter("li").delay(1000).fadeOut(1000);,但为什么淡出效果不起作用......任何线索?

这里是jsfiddle链接,任何人都可以看到并运行完整的代码 http://jsfiddle.net/mfrsousa/2gt4K/3/

感谢

修改

我有几个问题基于@Super cool提供的jsfiddle链接

1)为什么在绑定中引用firstName属性名称

<span data-bind="text:$data.firstName">

看到下面的代码,这种方式我绑定。在这里你可以看到我没有提到像first name or last name

这样的属性名称
<div id="dash" data-bind="foreach: {data : rows, beforeRemove : ElementFadeOut, afterAdd:ElementFadeIn}">
        <div data-bind="text:$data">
</div>

所以请告诉我为什么你提到属性名称的绑定如first name or last name ??

2)我见过 jsfiddle链接http://jsfiddle.net/supercool/2gt4K/27/ 在那里我看到$parent $root keyword用法的用法,但不明白这些关键字之间有什么区别$parent & $root keyword

从您的示例中可以看出,两个关键字$parent & $root keyword的工作方式相同。你能告诉我有什么不同吗?

2 个答案:

答案 0 :(得分:3)

  1. forEach绑定会创建一个新的子绑定上下文。当绑定呈现项时,默认情况下计算绑定表达式的上下文的$data属性是指列表项而不是视图模型。因此,如果需要在foreach绑定中引用视图模型,则需要引用父绑定上下文 - 在许多情况下,它等于根绑定上下文。你可以找到Knockout的绑定上下文here的详尽解释。

  2. 再次阅读this

  3. 因为Link是一个将网址与ID组合在一起的类。

  4. 什么不行?如果不工作,请在褪色后引用DOM中剩余的元素,请注意您在动画完成后负责从DOM中删除元素。再次,read the documentation

答案 1 :(得分:1)

让我试试。

  1. $ root是指viewModel的root内容,即使$ data表示相同,但​​它会根据您构建的视图而改变。

  2. $ parent将比$ data提前一步,即如果你有多个循环实例

  3. <强> VM:

        var mainLoopModel = function () {
            var self = this; // Root Level scope
            self.mainloop = ko.observableArray([{
                'firstName': 'jhon'
            }, {
                'firstName': 'sam'
            }]);
            self.lastName = ko.observable('peters');
        }
    
        ko.applyBindings(new mainLoopModel());
    

    查看:

       <div data-bind="foreach:mainloop">
        $data Value: <span data-bind="text:$data.firstName"></span> 
                      <span data-bind="text:$data.lastName"></span> --(1)
        $parent Value: <span data-bind="text:firstName"> </span> 
                       <span data-bind="text:$parent.lastName"></span>
        $root Value: <span data-bind="text:firstName"></span>
                     <span data-bind="text:$root.lastName"></span>
       </div>
    

    注意:如果在note(1)中的lastName之前删除$ data,则会出现未定义的错误,因为mainloop没有lastName,根模型具有lastName,因此您必须使用父级或更高级别访问

    为您提供样本 here

    1. self.links = ko.observableArray([new Link("", "")]);这里我们正在分配数据而非推送。是的,我们可以使用普通字符串,但我们应该牺牲双向绑定,如果你只是将数据绑定到用户无法改变的地方,那么你的想法很有效。

    2. 您应该使用beforeRemove而非afterRemove的小错误。 工作演示 here

    3. 请参阅文档 here ,这一点非常明白。