(更新)knockout.js学习——1.7例子——绑定的详细语法

创建自定义模板


1、注册绑定
添加子属性到ko.bindingHandlers.yourBindingName ={};注册绑定。


init和update可以只定义其中一个。


(1)初始化:init


  // 建立初始化状态,事件处理等等




(2)更新:update


    // 无论何时相关联的observable改变value时候
   // 基于应用values的DOM元素


(3)在DOM元素上使用: <div data-bind="yourBindingName: 


someValue"></div>




2、详细解释
   
   ko.bindingHandlers.yourBindingName ={
   init:function


(element,valueAccessor,allBindingsAccessor,viewModel){},
   update:function


(element,valueAccessor,allBindingsAccessor,viewModel)
   }


   参数:
   element——使用这个绑定的DOM元素。
            
   valueAccessor——Javascript函数。通过valueAccessor()可以得到应用到这个绑定的model上的当前属性值。
   
另一种翻译:得到是当前进入绑定的内容。是observable不是值。可以是表达式的值。


   allBindingsAccessor--Javascript函数。通过allBindingsAccessor()得到这个元素上所有model的属性值。
另一种翻译:得到其他绑定,并列入绑定属性中。一般用来访问其他绑定。这使您可以访问所有的其他绑定在同一列数据绑定属性。这通常是用于访问其他与此结合相互作用的绑定。这些绑定可能不会有任何相关的代码,只是一种方法,通过附加选项的约束力,除非你选择的多个属性为您的主要结合传递一个对象。例如,optionsvalue,optionstext,和optionscaption是绑定,只能通过选项选项结合。


   viewModel--传递给ko.applyBindings使用的view model参数,如果是模板内部的话,这个参数就是传递给模板的数据。

另一种翻译:通常以data代替避免混淆调用此参数数据。外模板绑定,这将提供对你的整体视图模型。在一个模板,这将被绑定到模板数据。例如,使用的模板的结合foreach选项时,视图模型参数会被设置为当前数组成员通过模板发送。大多数时候,valueaccessor会给你你想要的数据,而视图模型参数是特别有用,如果你需要一个对象是你的目标的时候,你的call/apply功能。





 (1) init回调:
  knockout在dom元素使用自定义绑定的时候会调用你的init函数。  init有两个重要的用途:为dom元素设置初始值;注册事件句柄,例如当用户点击或者编辑DOM元素的时候,可以改变相关的observable值的状态。ko会传递和update回调函数一样的参数。

你可以像让slideVisible在页面第一次显示的时候设置该元素的状态(但是不使用任何动画效果),而只是让动画在以后改变的时候再执行。


你可以这样来做:




ko.bindingHandlers.slideVisible = {
    init: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor


());
        // Get the current value of the current property we're 


bound to
        $(element).toggle(value);
        // jQuery will hide/show the element depending on 


whether "value" or true or false
    },


    update: function(element, valueAccessor, 


allBindingsAccessor) {
        // Leave as before
    }
};
这就是说giftWrap的初始值声明的是false(例如giftWrap: ko.observable(false)),然后让初始值会让关联的DIV隐藏,之后用户点击checkbox的时候会让元素显示出来。




(2)update回调


    通过visible绑定来控制一个元素的可见性,但是想让该元素在隐藏或者显示的时候加入动画效果。可以自定义自己的绑定来调用jquery的slideUp/slideDown函数。


ko.bindingHandlers.slideVisible = {
   update: function


(element,valueAccessor,allBindingsAccessor){
    // get the latest data that bound to
    var value = valueAccessor(), allBindings = 


allBindingsAccessor();
    // next,whether or not the supplied model property is 


observable,get its current value.
    var valueUnwrapped = ko.utils.unwrapObservable(value);
    // grab some more data from another bingding property
    var duration = allBindings.slideDuration || 500;
    // 500 is default duration unless otherwise specified
    // now manipulate the dom element
    if(valueUnwrapped == true) $(element).slideDown(duration);
    else $(element).slideUp(duration);
    }
  };




1、数组绑定


this.items = ko.observableArray([
    { id: 1, name: "Apple Pie" },
    { id: 2, name: "Pumpkin Pie" },
    { id: 3, name: "Blueberry Torte" }
]);
this.items.push({ id: 4, "Strawberry Shortcake" });


重要是要注意,ObservableArrays跟踪数组里的item更改,而不是单独的一个item的属性。在上面的例子中,如果你的应用需要跟踪item的name,那么name属性需要也加一个observable。


2、在IE6下,如果有空格要写&nbsp;否则不呈现空格。




一、控制文本和展现
1、text绑定
2、visible绑定
3、html绑定
<div data-bind="html: details"></div>
 
<script type="text/javascript">
    var viewModel = {
        details: ko.observable() // Initially blank
    };
    viewModel.details("<em>For further details, view the 


report <a href='report.html'>here</a>.</em>"); // HTML content 


appears 
</script>


4、如果你提供的不是数字或者字符串,你传递的是对象或数组等,innerHTML/text bingding和yourParameter.toString()效果一样。


5、css绑定
<div data-bind="css: { profitWarning: currentProfit() < 0 }">
   Profit Information
</div>
 
<script type="text/javascript">
    var viewModel = {
        currentProfit: ko.observable(150000) // Positive 


value, so initially we don't apply the "profitWarning" class
    };
    viewModel.currentProfit(-50); // Causes the 


"profitWarning" class to be applied
</script>


当currentProfit()<0时,css样式名"profitWarning"就增加,否则移除这个css。


动态切换两个css:
<div data-bind="css: profitStatus">
   Profit Information
</div>
 
<script type="text/javascript">
    var viewModel = {
        currentProfit: ko.observable(150000)
    };
 
    // Evalutes to a positive value, so initially we apply the 


"profitPositive" class
    viewModel.profitStatus = ko.computed(function() { // 


computed
        return this.currentProfit() < 0 ? "profitWarning" : 


"profitPositive";
    }, viewModel);
 
    // Causes the "profitPositive" class to be removed and 


"profitWarning" class to be added
    viewModel.currentProfit(-50);
</script>




可以同时使用多个css绑定:
<div data-bind="css: { profitWarning: currentProfit() < 0, majorHighlight: isSevere }">


当类标志不合法时,如profitWarning,给其加上引号:'profitWarning'




6、style 绑定
<div data-bind="style: { color: currentProfit() < 0 ? 'red' : 


'black', fontWeight: isSevere() ? 'bold' : '' }">...</div>




7、attr绑定
<a data-bind="attr: { href: url, title: details }">
    Report
</a>
 
<script type="text/javascript">
    var viewModel = {
        url: ko.observable("year-end.html"),
        details: ko.observable("Report including final year-


end statistics")
    };
</script>


attr属性名字不合法时,加上引号就可以。


二、控制流绑定
1、foreach绑定


   foreach绑定复制进入一个数组的标记部分,绑定每一个复制标记到相应的数组条目。可以和其他控制流的if、with一起使用。


<h4>People</h4>
<ul data-bind="foreach: people">
    <li>
        Name at position <span data-bind="text: $index"> 


</span>:
        <span data-bind="text: name"> </span>
        <a href="#" data-bind="click: 


$parent.removePerson">Remove</a>
    </li>
</ul>
<button data-bind="click: addPerson">Add</button>
function AppViewModel() {
    var self = this;
 
    self.people = ko.observableArray([
        { name: 'Bert' },
        { name: 'Charles' },
        { name: 'Denise' }
    ]);
 
    self.addPerson = function() {
        self.people.push({ name: "New at " + new Date() });
    };
 
    self.removePerson = function() {
        self.people.remove(this);
    }
}
 
ko.applyBindings(new AppViewModel());






$index:序号
$parent:上一级元素


(1)$data


foreach块可以在数组项引用属性,但是如果希望在数组条目本身时引入属性:
用$data代表每一项。
显示每一项的具体内容:
<td data-bind="text: $data.firstName"></td>




(2)别名:as,加上引号,是给一个新名字为新的变量,不是改变值。
任何foreach循环内部,都会引用别名进入现在的数组条目。这在祖先元素已经嵌套foreach块,而且你需要在更高一层引用一个条目声明时很有用。
<ul data-bind="foreach: { data: categories, as: 'category' }">
    <li>
        <ul data-bind="foreach: { data: items, as: 'item' }">
            <li>
                <span data-bind="text: category.name"></span>:
                <span data-bind="text: item"></span>
            </li>
        </ul>
    </li>
</ul>
 
<script>
    var viewModel = {
        categories: ko.observableArray([
            { name: 'Fruit', items: [ 'Apple', 'Orange', 


'Banana' ] },
            { name: 'Vegetables', items: [ 'Celery', 'Corn', 


'Spinach' ] }
        ])
    };
    ko.applyBindings(viewModel);
</script>


(3)只有部分元素循环遍历,加上包裹元素在内部(如例子中的span标签)。使用<!---->


<ul>
    <li class="header">Header item</li>
    <!-- ko foreach: myItems -->
        <li>Item <span data-bind="text: $data"></span></li>
    <!-- /ko -->
</ul>
 
<script type="text/javascript">
    ko.applyBindings({
        myItems: [ 'A', 'B', 'C' ]
    });
</script>




(4)想要显示销毁的条目,使用includeDestroyed
<div data-bind='foreach: { data: myArray, includeDestroyed: 


true }'>
    ...
</div>


(5)执行动画效果
afterRender/afterAdd/beforeRemove/beforeMove/afterMove 
<ul data-bind="foreach: { data: myItems, afterAdd: 


yellowFadeIn }">
    <li data-bind="text: $data"></li>
</ul>
 
<button data-bind="click: addItem">Add</button>
 
<script type="text/javascript">
    ko.applyBindings({
        myItems: ko.observableArray([ 'A', 'B', 'C' ]),
        yellowFadeIn: function(element, index, data) {
            $(element).filter("li")
                      .animate({ backgroundColor: 'yellow' }, 


200)
                      .animate({ backgroundColor: 'white' }, 


800);
        },
        addItem: function() { this.myItems.push('New item'); }
    });
</script>


afterRender: 在foreach块复制到文档中或foreach初始化,或新的条


目增加到数组中,konckout将会提供如下参数到回调函数中:
     插入到数组中的dom元素
     对应被绑定的数据条目


afterAdd:当新条目增加到数组中时激发。一般用来回调一个方法,比如$().fadeIn(),得到动画过度当条目增加时。knockout会提供如下参数:
 被增加的dom节点,增加的数组元素index,增加的数组元素






beforeMove:当数组条目在数组中的位置发生改变,且在对应dom节点被移除前 被激发。它适用于所有序号改变的数组元素,所以当你插入一个数组条目在数组中,回调函数会激发其他元素,知道他们的序号位置已经增加了1。可以使用beforeMove来存储收影响元素的原始屏幕坐标。这样你可以使他们在afterMove回调函数中动画过度。
提供的回调参数:
将要移动的dom节点,移动的数组元素的序号,移动的数组元素。


afterMove:当数组中的数组条目已经改变位置时,在foreach已经更新dom来匹配之后,被激发。
afterMove适用于所有序号被改变的数组元素,回调函数会激发其他元素,直到他们的序号位置都已经增加一。
konockout提供的回调参数:
将要被移除的dom节点,移动的数组元素的序号,移动的数组元素。






2、if绑定


if和visible


if和visible差不多。不同在于,使用visible,包括标签保持在dom中,经常使用data-bind属性——visible绑定使用css来切换标签的可见性。if只在表达式为真的情况下适用于增加或移除dom中绑定的后代元素包括的标签。


例子:
<ul data-bind="foreach: planets">
    <li>
        Planet: <b data-bind="text: name"> </b>
        <div data-bind="if: capital">
            Capital: <b data-bind="text: capital.cityName"> 


</b>
        </div>
    </li>
</ul>
 
 
<script>
    ko.applyBindings({
        planets: [
            { name: 'Mercury', capital: null }, 
            { name: 'Earth', capital: { cityName: 'Barnsley' } 


}        
        ]
    });
</script>
在以上例子中,因为if,capital为null就不用继续执行,发生错误:


计算后续capital.cityName不存在的属性了。在javascript中,可以判断if:capital判断是否为空,但是不允许计算为空的值:


capital.cityName。


if后面的语句为true,显示包含的标签。
if后面的语句为false,包含的标签将会从document中移走而不是适用于任何刚开始的绑定。


如果表达式提及到任何可观测值,当它们改变时表达式会被重新计算。
相应的,带有if标签块将会动态增加和移除当表达式结果发生改变时。
data-bind属性将会被用于一个新的副本包含标签。


当想要实现控制某一部分标签显示隐藏,
使用<!-- ko --><!-- /ko -->
<ul>
    <li>This item always appears</li>
    <!-- ko if: someExpressionGoesHere -->
        <li>I want to make this item present/absent 


dynamically</li>
    <!-- /ko -->
</ul>




3、ifnot绑定
和if一样。完全可以用if代替。


4、with绑定
with绑定创建了一个新的上下文,所以后代元素被绑定一个详细的对象上下文。
可以任意使用其他控制流绑定如if/foreach和嵌套with绑定。


以下是一个简单的切换绑定上下文到子对象。
注意data-bind属性,没有必要加上latitude和longitude的前缀


coords.。因为绑定上下文已经切换到coords了。
<h1 data-bind="text: city"> </h1>
<p data-bind="with: coords">
    Latitude: <span data-bind="text: latitude"> </span>,
    Longitude: <span data-bind="text: longitude"> </span>
</p>
 
<script type="text/javascript">
    ko.applyBindings({
        city: "London",
        coords: {
            latitude:  51.5001524,
            longitude: -0.1262362
        }
    });
</script>




复杂一点的with例子:
<form data-bind="submit: getTweets">
    Twitter account:
    <input data-bind="value: twitterName" />
    <button type="submit">Get tweets</button>
</form>
 
<div data-bind="with: resultData">
    <h3>Recent tweets fetched at <span data-bind="text: 


retrievalDate"> </span></h3>
    <ol data-bind="foreach: topTweets">
        <li data-bind="text: text"></li>
    </ol>
 
    <button data-bind="click: $parent.clearResults">Clear 


tweets</button>
</div>




function AppViewModel() {
    var self = this;
    self.twitterName = ko.observable('@example');
    self.resultData = ko.observable(); // No initial value
 
    self.getTweets = function() {
        var name = self.twitterName(),
            simulatedResults = [
                { text: name + ' What a nice day.' },
                { text: name + ' Building some cool apps.' },
                { text: name + ' Just saw a famous celebrity 


eating lard. Yum.' }
            ];
 
        self.resultData({ retrievalDate: new Date(), 


topTweets: simulatedResults });
    }
 
    self.clearResults = function() {
        self.resultData(undefined);
    }
}
 
ko.applyBindings(new AppViewModel());




with绑定动态增加移除后代元素依赖于联系的值是null/undefined或非空。
如果需要访问父元素绑定的上下文中的data/functions,可以使用


$parent和root。




关于with的子属性设置的两种写法:
1、写在viewmodel对象中
var viewModel ={
  lcon: {
                lname: "lfwefw ",
                showCon: [
                 { name: "s", textInput: "second" },
                 { name: "t", textInput: "third" },
                 { name: "f", textInput: "first" }]
            }




}


2、用创建viewModel函数的写法
function AppViewModel() {
    var self = this;
    self.resultData({ retrievalDate: new Date(), topTweets:    


 simulatedResults });
}




与其他没有包括标签一样:
<ul>
    <li>Header element</li>
    <!-- ko with: outboundFlight -->
        ...
    <!-- /ko -->
    <!-- ko with: inboundFlight -->
        ...
    <!-- /ko -->
</ul>

例子:

<html>

<head>
    <title></title>


    <script type="text/javascript" src="js/jquery-1.8.2.min.js"></script>
    <script type="text/javascript" src="js/jquery.tmpl.js"></script>
    <script type="text/javascript" src="js/knockout-3.1.0.js"></script>
    <script type="text/javascript" src="js/knockout.simpleGrid.js"></script>
    <style type="text/css">
    </style>
</head>
<body>
    <form data-bind="submit: showDetail">
        <div>
            Your Account:<input type="text" data-bind="value: inputCon" />
            <button type="submit">提交信息</button>
        </div>
    </form>
    <div data-bind="visible: hiddenDetail">
        <div data-bind="text: inputCon"></div>
        <div data-bind="with: lcon">
            <div data-bind="text: lname"></div>
            <div data-bind="foreach: showCon">
                hello:<span data-bind="text: name"></span>
                <span data-bind=" text: name"></span>
                <br />


            </div>
        </div>
        <button type="submit" data-bind="click: clearCon">隐藏</button>
    </div>


    <script type="text/javascript">
        var viewModel = {
            inputCon: ko.observable("@mail"),
            showDetail: ko.observable(true),
            hiddenDetail: ko.observable(false)
           ,


            lcon: {
                lname: "lfwefw ",
                showCon: [
                 { name: "s", textInput: "second" },
                 { name: "t", textInput: "third" },
                 { name: "f", textInput: "first" }]
            }
        };
        viewModel.showDetail = function () { viewModel.hiddenDetail(true); }
        viewModel.clearCon = function () { viewModel.hiddenDetail(false); }
        ko.applyBindings(viewModel);
    </script>

</body>

</html>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值