Angular JS中ng屬性的實(shí)現(xiàn)細(xì)節(jié)

概述

Angular JS為很多屬性實(shí)現(xiàn)了對(duì)應(yīng)的directive。通過[ng-]開頭的屬性實(shí)現(xiàn)對(duì)應(yīng)的屬性與scope數(shù)據(jù)進(jìn)行綁定支鸡。如:ng-disabled='enabled'就會(huì)把scope.enabled與元素的disabled屬性進(jìn)行綁定。改變scope.enabled的值昏翰,元素的disabled屬性的值也會(huì)變化苍匆。

支持的屬性

第一類總共有12個(gè)屬性刘急,如下:

屬性 ng屬性
selected ng-selected
checked ng-checked
disabled ng-disabled
readOnly ng-readonly
required ng-required
open ng-open
minlength ng-minlength
maxlength ng-maxlength
min ng-min
max ng-max
pattern ng-pattern
step ng-step

在這一類中棚菊,directive會(huì)去利用$scope的watcher方法監(jiān)控?cái)?shù)據(jù)模型,如果有變動(dòng)叔汁,就會(huì)設(shè)置屬性值统求。需要注意的是ng-checked和ng-module綁定了相同的值,ng-checked將會(huì)失效据块。

第二類總共有3個(gè)码邻,如下:

屬性 ng屬性
src ng-src
srcset ng-srcset
href/xlink:href ng-href

在這一類中,directive會(huì)利用attr的$observe方法監(jiān)控ng屬性值的變化另假,然后再去設(shè)置屬性值像屋,同時(shí)還會(huì)把值寫入元素的property中去。需要注意的是ng-href實(shí)現(xiàn)了普通元素和SVG元素的統(tǒng)一處理边篮。

實(shí)現(xiàn)細(xì)節(jié)

第一類ng屬性有兩種實(shí)現(xiàn)方式己莺,其實(shí)現(xiàn)本質(zhì)上是一樣的奏甫,關(guān)鍵代碼:

forEach(BOOLEAN_ATTR, function(propName, attrName) {  
// binding to multiple is not supported  
    if (propName === 'multiple')
        return;  
    function defaultLinkFn(scope, element, attr) {   
        cope.$watch(attr[normalized], function ngBooleanAttrWatchAction(value) {
            attr.$set(attrName, !!value);   
        });
    }
    var normalized = directiveNormalize('ng-' + attrName);  
    var linkFn = defaultLinkFn;  
    if (propName === 'checked') {    
        linkFn = function(scope, element, attr) { 
        // ensuring ngChecked doesn't interfere with ngModel when both are set on the same input     
            if (attr.ngModel !== attr[normalized]) {        
                defaultLinkFn(scope, element, attr);      
            }
        };
    }
    ngAttributeAliasDirectives[normalized] = function() {
        return {
            restrict: 'A',
            priority: 100,
            link: linkFn    
        };  
    };
});

// aliased input attrs are evaluatedforEach(ALIASED_ATTR, function(htmlAttr, ngAttr) {
  ngAttributeAliasDirectives[ngAttr] = function() {
    return {
      priority: 100,
      link: function(scope, element, attr) {
        //special case ngPattern when a literal regular expression value
        //is used as the expression (this way we don't have to watch anything).
        if (ngAttr === 'ngPattern' && attr.ngPattern.charAt(0) === '/') {
          var match = attr.ngPattern.match(REGEX_STRING_REGEXP);
          if (match) {
            attr.$set('ngPattern', new RegExp(match[1], match[2]));
            return; 
         }
        }
        scope.$watch(attr[ngAttr], function ngAttrAliasWatchAction(value) {
          attr.$set(ngAttr, value);
        });
      }
    };
  };
});

其中最為關(guān)鍵的是directive中的link函數(shù)里的內(nèi)容:

scope.$watch(attr[ngAttr], function ngAttrAliasWatchAction(value) {
   attr.$set(ngAttr, value); 
});

在這里實(shí)現(xiàn)了對(duì)數(shù)據(jù)的監(jiān)控,以及變化時(shí)的處理凌受。
第二類在實(shí)現(xiàn)的時(shí)候和第一種大同小異阵子,有區(qū)別的也是directive的link函數(shù):

link: function(scope, element, attr) {
  var propName = attrName, 
  name = attrName;
  if (attrName === 'href' &&      toString.call(element.prop('href')) === '[object SVGAnimatedString]') {
    name = 'xlinkHref';
    attr.$attr[name] = 'xlink:href';
    propName = null; 
  }
  attr.$observe(normalized, function(value) {
    if (!value) {
      if (attrName === 'href') {
        attr.$set(name, null);
      }
      return;
    }
    attr.$set(name, value); 
    // on IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist
    // then calling element.setAttribute('src', 'foo') doesn't do anything, so we need
    // to set the property as well to achieve the desired effect.
    // we use attr[attrName] value since $set can sanitize the url.
    if (msie && propName) element.prop(propName, attr[name]);
  });

這里面實(shí)現(xiàn)的功能稍微多一點(diǎn)點(diǎn),首先會(huì)針對(duì)href屬性進(jìn)行SVG的兼容胜蛉,然后通過attr的$observe方法監(jiān)控屬性值的變化挠进。在屬性值發(fā)生變化時(shí)首先會(huì)設(shè)置到attr中去,然后會(huì)根據(jù)需要設(shè)置到element的property中去誊册。

使用樣例

<!DOCTYPE html><html lang="en" ng-app="app">
<!--<html>-->
<head>
    <title>Test</title>
</head>
<body ng-controller="testCtrl">
<div>
    <input ng-readonly="enable" ng-model="data">
    <input type="button" value="click" ng-click="enable=!enable">
</div>
<div>
    <a ng-href="{{data}}">link</a>
</div>
</body>
<script src="./node_modules/angular/angular.js" type="text/javascript"></script>
<script>
    angular.module("app",[]).controller("testCtrl",["$scope",function($scope){
        $scope.enable = false;
        $scope.data = "";
    }]);
</script>
</html>

在這個(gè)樣例中實(shí)現(xiàn)了點(diǎn)擊按鈕禁用或啟用輸入框领突,在輸入框中輸入數(shù)據(jù)會(huì)改變a標(biāo)簽的href屬性值。
從中可以看到解虱,對(duì)于第一類ng屬性可以直接寫數(shù)據(jù)名稱攘须,而對(duì)于第二類ng屬性則需要使用雙花括號(hào)括起來。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末殴泰,一起剝皮案震驚了整個(gè)濱河市于宙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌悍汛,老刑警劉巖捞魁,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異离咐,居然都是意外死亡谱俭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門宵蛀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來昆著,“玉大人,你說我怎么就攤上這事术陶〈斩” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵梧宫,是天一觀的道長(zhǎng)接谨。 經(jīng)常有香客問我,道長(zhǎng)塘匣,這世上最難降的妖魔是什么脓豪? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮忌卤,結(jié)果婚禮上扫夜,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好笤闯,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布现拒。 她就那樣靜靜地躺著,像睡著了一般望侈。 火紅的嫁衣襯著肌膚如雪印蔬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天脱衙,我揣著相機(jī)與錄音侥猬,去河邊找鬼。 笑死捐韩,一個(gè)胖子當(dāng)著我的面吹牛退唠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播荤胁,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼瞧预,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了仅政?” 一聲冷哼從身側(cè)響起垢油,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎圆丹,沒想到半個(gè)月后滩愁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡辫封,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年硝枉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片倦微。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡妻味,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出欣福,到底是詐尸還是另有隱情责球,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布劣欢,位于F島的核電站棕诵,受9級(jí)特大地震影響裁良,放射性物質(zhì)發(fā)生泄漏凿将。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一价脾、第九天 我趴在偏房一處隱蔽的房頂上張望牧抵。 院中可真熱鬧,春花似錦、人聲如沸犀变。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽获枝。三九已至蠢正,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間省店,已是汗流浹背嚣崭。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留懦傍,地道東北人雹舀。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像粗俱,于是被迫代替她去往敵國(guó)和親说榆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容