2013-07-19 43 views
2

在AngularJS中,我有基本跨越的指令。我知道,當我使用它時,通常是transcluded input或textarea,如果有,我希望$觀察它的模型以進行更改。但是我沒有權限訪問transcluded內容的屬性,只能訪問根元素的哪個指令被調用。 Transcluded範圍以及(也許範圍。$$ nextSibling可以幫助,但有些事告訴我,這是地獄的方式:))。AngularJS - 觀察transcluded元素的模型

那麼有沒有辦法做到這一點,而不需要添加另一個參數(屬性)元素的指令稱爲?

指令模板

<div ng-transclude> 
    <someContent>...</someContent> 
    <!-- HERE IS INPUT TRANSCLUDED --> 
</div> 

指令使用

<div my-directive="somedata">       //this attribs are accessable 
    <input ng-model="iWantToWatchThisInMyDirective" /> //but i want to access this also 
</div> 
+0

你想達到什麼樣的? –

+0

我想知道模型文本是否爲空,並且應用一些邏輯,比如向指令的根元素添加類。 –

+1

最好的方法是在屬性中傳遞參數iWantToWatchThisInMyDirective,並觀察該屬性,但仍然如果您不想要那麼你可以在家長控制器中觀看模型,並在父控制器中廣播一個事件,並聽取指令 –

回答

0

這裏是我的解決方案:

我創造了第二個指令:輸入(受限制的元素,所以每一個輸入具有一)。在輸入指令我廣播每次更改元素的範圍:

link: function (scope, element: JQuery, attrs: ng.IAttributes) { 
    if(typeof attrs.ngModel !== "undefined") { 
    scope.$watch(attrs.ngModel, function (newValue, oldValue) { 
     scope.$broadcast('valueChanged'+scope.$id, newValue, oldValue); 
    }); 
    } 
} 

範圍的$ id是隻用於確保事件名稱是每個輸入唯一的。

現在,在其他任何指令,我可以聽改變任何輸入的事件:

link: function (scope, element:JQuery, attrs:ng.IAttributes) { 
    //My input is last child everytime.. 
    var children = element.find("input"); 
    var lastInput = angular.element(children[children.length - 1]); 
    var lastInputScope = lastInput.scope(); 

    var unregister = lastInputScope.$on('valueChanged' + lastInputScope.$id, 
             function (event, newValue, oldValue) { 
    //do whatever you want... 
    }); 

    scope.$on('$destroy', function() { 
    unregister(); 
    }); 
} 
0

這裏的另一種方式,您可以使用$scope.$watch做到這一點。這段代碼是用jQuery編寫的。

angular.module('sample').directive('sampleDirective', function() { 
    'use strict'; 

    // Returns a JQLite object for the first input element we transcluded, 
    // allowing us to pick information from it 
    function findInput(clone) { 
     for (var i = 0; i < clone.length; i++) { 
      if (clone[i].nodeName.toLowerCase() == 'input') { 
       return angular.element(clone[i]); 
      } 
     } 
    } 

    return { 
     transclude: true, 
     link: function (scope, element, attrs, ctrl, transclude) { 

      transclude(function (clone) { 
       var input = findInput(clone); 
       if (input) { 

        // Watch for changes on our select element's model 
        scope.$watch(input.attr('ng-model'), function (val) { 

         // Do things 
         console.log('My updated model:', val); 
        }); 
       } 
      }); 
     } 
    }; 
}); 

這裏假設你的模型可在同一範圍內的指令是上。如果您的指令有一個分離的範圍,你可以改變手錶的語句來監控ng-model串上$parent範圍:

scope.$watch('$parent.' + input.attr('ng-model')