欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
前端開(kāi)發(fā)框架Bootstrap和KnockoutJS

江湖中那場(chǎng)異常慘烈的廝殺,如今都快被人遺忘了。當年,所有的武林同道為了同一個(gè)敵人都拼盡了全力,為數不多的幸存者心灰意冷,隱姓埋名,遠赴他鄉,他們將唯一的希望寄托給時(shí)間。少年子弟江湖老,紅顏少女的鬢邊也有了白發(fā)。多年以后,聽(tīng)聞那個(gè)魔頭也不久于人世,他們欣欣然回鄉,卻發(fā)現當初殫精竭慮研究出來(lái)對付敵人的招數全無(wú)用處,曾經(jīng)受人尊敬的大俠現在被稱(chēng)為——新手 or 菜鳥(niǎo)。月下小酌,孤獨的他們對著(zhù)夜空舉起酒杯,吼一聲:“走你,IE6!”

-----------------------------------------------------割--------------------------------------------------------------------

Bootstrap是一個(gè)前端框架,解放Web開(kāi)發(fā)者的好東東,展現出的UI非常高端大氣上檔次,理論上可以不用寫(xiě)一行css。只要在標簽中加上合適的屬性即可。請參看Bootstrap中文文檔,這是3.0版本。

KnockoutJS是一個(gè)JavaScript實(shí)現的MVVM框架。非常棒。比如列表數據項增減后,不需要重新刷新整個(gè)控件片段或自己寫(xiě)JS增刪節點(diǎn),只要預先定義模板和符合其語(yǔ)法定義的屬性即可。簡(jiǎn)單的說(shuō),我們只需要關(guān)注數據的存取。官網(wǎng)文檔。

Bootstrap負責UI,KnockoutJS負責數據綁定,兩者相得益彰,Web前端必備利器。

我們來(lái)做一個(gè)簡(jiǎn)單的例子展示一下它們的威力。

要擱以前,實(shí)現類(lèi)似功能,可以有兩個(gè)選擇:a)直接操作DOM,夠喝一壺,一般喜歡展現技術(shù)同學(xué)的首選;b)借助各種拉風(fēng)的重量級JS框架,比如extjs,使用它們的API以減少工作量,不過(guò)這些框架的學(xué)習曲線(xiàn)也挺扭曲。當然本文所說(shuō)的兩個(gè)框架也涉及到各自的JS類(lèi)庫,but,提供給開(kāi)發(fā)人員的使用方式是完全不同的,后者更松散(廢話(huà),兩個(gè)當然比一個(gè)松散)、靈活,且是基于特性聲明的方式,個(gè)人表示相當不錯。下面就讓我們開(kāi)始碼吧。

首先搭個(gè)初步的框架:

<div id="divAuthManage" class="row" style="margin-top: 30px;">    <div class="col-md-4 col-sm-4 col-xs-6">        <div>            <div class="input-group">                <span class="input-group-addon">用戶(hù)名</span>                <input id="inputUserName" type="text" class="form-control" />                <span class="btn btn-primary input-group-btn">添加</span>            </div>            <div id="divWaring" class="alert alert-warning" style="display: none;"></div>        </div>        <table class="table table-bordered table-hover" style="margin-top: 20px;">            <thead>                <tr>                    <th>用戶(hù)ID</th>                    <th>用戶(hù)名</th>                    <th style="text-align: center;">刪除</th>                </tr>            </thead>            <tbody>            </tbody>        </table>    </div>    <div class="col-md-8 col-sm-8 col-xs-12">        @foreach (AreaElement area in Model.Areas)        {            <div class="panel panel-default">                <div class="panel-heading">                    @{if (area.Sites.Count == 0)                      {                        <label class="checkbox">                            <input type="checkbox" value="@area.Code" />                            @area.Name                        </label>                      }                      else                      {                        @area.Name                      }                    }                </div>                @if (area.Sites.Count > 0)                {                    <div class="panel-body">                        @foreach (SiteElement site in area.Sites)                        {                            <label class="checkbox-inline">                                <input type="checkbox" value="@site.Code" />@site.Name                            </label>                        }                    </div>                }            </div>        }        <p class="text-right">            <button type="button" class="btn btn-default">保存</button>        </p>    </div></div>

這里就用到了bootstrap,如果一個(gè)元素使用了相應的class,它就會(huì )呈現bootstrap中預定義的樣式。bootstrap還提供了data-xxx屬性,這是用來(lái)以聲明方式使用組件,這里沒(méi)有涉及。now,界面如下:

圖中標注了需要改進(jìn)的兩個(gè)地方,此時(shí)先不考慮。我們現在要先把數據從后臺取出,以及其它的一些操作,于是引進(jìn)KnockoutJS。接觸過(guò)WPF的都知道ViewModel的概念,說(shuō)白了就是將前端分為UI和交互邏輯,ViewModel就負責交互邏輯,knockoutJS也有這個(gè)東西。結合例子具體來(lái)看:

window.adApp.authManageViewModel = (function (ko) {    var userList = ko.observableArray(),        error = ko.observable(),        addUser = function (username) {            this.clearError();            if (!username) {                error("請輸入用戶(hù)名.");            }            else {                this._ajaxRequest("post", '/api/UserAuthority/AddUser', { "": username }, function (data) {                    if (!data.IsSucceed)                        this.error(data.Message);                    else {                        var user = new User(data.Data);                        this.userList.unshift(user);                    }                });            }        },        deleteUser = function (user) {            this._ajaxRequest("delete", '/api/UserAuthority/DeleteUser', { "": user.userid }, function (data) {                if (!data.IsSucceed)                    this.error(data.Message);                else {                    this.userList.remove(user);                }            });        },        getUsers = function () {            this._ajaxRequest("get", '/api/UserAuthority/GetUsers', null, function (data) {                this.userList.removeAll();                for (var i = 0; i < data.length; i++) {                    userList.push(new User(data[i]));                }            });        },        selectUser = function (user) {            for (var i = 0; i < userList().length; i++) {                userList()[i].selected(false);            }            user.selected(true);            this._ajaxRequest("get", '/api/UserAuthority/GetAccessNavItems', { userid: user.userid }, function (data) {                user.navitems.removeAll();                for (var i = 0; i < data.length; i++) {                    user.navitems.push(data[i]);                }            });        },        clearError = function () { error(""); };    var viewmodel = {        userList: userList,        error: error,        _ajaxRequest: ajaxRequest,        addUser: addUser,        deleteUser: deleteUser,        clearError: clearError,        _getUsers: getUsers,        selectUser: selectUser,        currentUser: ko.computed(function () {            for (var i = 0; i < userList().length; i++) {                if (userList()[i].selected()) {                    return userList()[i];                }            }            return null;        })    };    viewmodel._getUsers();    return viewmodel;    function ajaxRequest(type, url, data, callback) { // Ajax helper        this.clearError();        $.ajax({            url: url,            data: data,            type: type,            dataType: "json",            context: this,//指定this為當前對象viewmodel            success: callback,            error: function () {                this.error("服務(wù)器錯誤.");            }        });    }})(ko);// Initiate the Knockout bindingsko.applyBindings(window.adApp.authManageViewModel);

window.adApp.authManageViewModel就是ViewModel,它包含了兩個(gè)屬性(UserList為用戶(hù)集合,error為提示信息,準確的命名應該類(lèi)似msg,懶得改了)和若干函數(和服務(wù)端交互)。ko.applyBindings將該ViewModel綁定到頁(yè)面。上述代碼還涉及到兩個(gè)類(lèi)型:

function NavItem(data) {    var self = this;    data = data || {};    // Persisted properties    self.code = data.code;    self.name = data.name;}function User(data) {    var self = this;    data = data || {};    // Persisted properties    self.userid = data.userid;    self.username = data.username;    data.navitems = data.navitems || [];    self.navitems = ko.observableArray(data.navitems);    self.selected = ko.observable(false);}User.prototype.updateNavs = function () {    var user = this;    window.adApp.authManageViewModel._ajaxRequest(        "put", '/api/UserAuthority/UpdateNavItems?userid=' + user.userid, { "": user.navitems()}, function (data) {            if (!data.IsSucceed)                this.error(data.Message);            else {                this.error("保存成功!");            }        });}

現在頁(yè)面代碼如下:

<div id="divAuthManage" class="row" style="margin-top: 30px;">    <div class="col-md-4 col-sm-4 col-xs-6">        <div>            <div class="input-group">                <span class="input-group-addon">用戶(hù)名</span>                @*data-bind="input: clearError" 不支持input綁定,so換用自定義綁定,or采用event綁定如下*@                <input id="inputUserName" type="text" class="form-control" data-bind="event: { input: clearError }" />                <span class="btn btn-primary input-group-btn" data-bind="click: function (data, event) { addUser(inputUserName.value) }">添加</span>            </div>            <div id="divWaring" class="alert alert-warning" style="display: none;" data-bind="animVisible: error"></div>        </div>        @*如果userList集合有項,才顯示該表格,注意if、ifnot的作用范圍不包括table標記本身,而是從thead開(kāi)始*@        <table data-bind="if: userList().length > 0" class="table table-bordered table-hover" style="margin-top: 20px;">            <thead>                <tr>                    <th>用戶(hù)ID</th>                    <th>用戶(hù)名</th>                    <th style="text-align: center;">刪除</th>                </tr>            </thead>            <tbody data-bind="foreach: userList">                <tr data-bind="css: { success: selected }, click: function (data, event) { $parent.selectUser($data) }">                    <td><span data-bind="text: userid"></span></td>                    <td><span data-bind="text: username"></span></td>                    <td style="text-align: center;">                        <button type="button" class="btn btn-default btn-xs" data-bind="click: function (data, event) { $parent.deleteUser($data) }, clickBubble: false">                            <span class="glyphicon glyphicon-remove"></span>                        </button>                    </td>                </tr>            </tbody>        </table>    </div>    @*將下面div的綁定對象設為currentUser,如果currentUser為空,則該div中的內容不會(huì )顯示*@    <div class="col-md-8 col-sm-8 col-xs-12" data-bind="with: currentUser">        @foreach (AreaElement area in Model.Areas)        {            <div class="panel panel-default">                <div class="panel-heading">                    @{if (area.Sites.Count == 0)                      {                        <label class="checkbox">                            <input type="checkbox" value="@area.Code" data-bind="checked: navitems" />                            @area.Name                        </label>                      }                      else                      {                        @area.Name                      }                    }                </div>                @if (area.Sites.Count > 0)                {                    <div class="panel-body">                        @foreach (SiteElement site in area.Sites)                        {                            <label class="checkbox-inline">                                <input type="checkbox" value="@site.Code" data-bind="checked: navitems" />@site.Name                            </label>                        }                    </div>                }            </div>        }        <p class="text-right">            <button type="button" class="btn btn-default" data-bind="click: updateNavs">保存</button>        </p>    </div></div>

代碼中加了很多data-bind屬性,作用不言自明。需要注意的是所謂自定義綁定。當綁定的值變動(dòng)了,希望執行額外的邏輯(和c#中的事件相似),就會(huì )用到。這里,當error的值有變動(dòng),為空時(shí)提示面板隱藏,否則顯示:

<div id="divWaring" class="alert alert-warning" style="display: none;" data-bind="animVisible: error"></div>

animVisible就是一個(gè)自定義綁定,定義如下:

ko.bindingHandlers.animVisible = {    update: function (elem, valueAccessor) {        var error = ko.unwrap(valueAccessor());        if (error) {            elem.innerText = error;            $(elem).show(300);        }        else {                        $(elem).hide(300);            elem.innerText = "";        }    }};

OK,接下來(lái),當點(diǎn)擊表格的每一行,currentUser就會(huì )自動(dòng)計算得到(ko.computed),并反饋到界面,綁定了該字段的div內部的相應節點(diǎn)的狀態(tài)也會(huì )相應變化(checkbox)。保存啥的就不說(shuō)了。綜上所述,除了必要的與后臺交互的代碼,涉及到操作UI和DOM節點(diǎn),我們不需要寫(xiě)一行JS,很爽很舒服。

ps:本來(lái)想寫(xiě)詳細點(diǎn),結果發(fā)現寫(xiě)一大堆還不如幾行代碼來(lái)的清楚。文中若有錯誤之處,請及時(shí)告知,大家交流,共同進(jìn)步。

 

轉載請注明本文出處:http://www.cnblogs.com/newton/p/3328058.html

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
bootstrap中多個(gè)modal彈出的問(wèn)題解決方案
第十六節,Bootstrap彈出框和警告框插件
FormData圖片上傳預覽插件
Bootstrap每天必學(xué)之模態(tài)框(Modal)插件
bootstrap model彈出框的使用
Bootstrap學(xué)習
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久