2015-04-28 56 views
7

我是Angular的新手,仍然痛苦地將自己的頭包裹在自定義指令中。angularjs將ngModel從包裝指令傳遞到包裝指令

我想用它包裝成我的自定義指令重複使用HTML

<ui-select ng-model="model.selectedLanguages" multiple search-enabled="true" theme="select2" style="width: 300px;"> 
    <ui-select-match placeholder="Pick one...">{{$item.name}}</ui-select-match> 
    <ui-select-choices repeat="lang.id as lang in langs |filter: { name : $select.search }"> 
     <div ng-bind-html="lang.name | highlight: $select.search" ></div> 
    </ui-select-choices> 
</ui-select> 

的該位:

<language-picker ng-model="model.selectedLanguages"/> 

是這樣的:

app.directive('languagePicker', function() { 
      return { 
       template : '<ui-select ng-model="**PARENT'S NGMODEL**" multiple search-enabled="true" theme="select2" style="width: 300px;"><ui-select-match >{{$item.name}}</ui-select-match><ui-select-choices repeat="lang.id as lang in langs | filter: { name : $select.search }"><div ng-bind-html="lang.name | highlight: $select.search"></div></ui-select-choices></ui-select>', 
       restrict : 'E', 
       require : 'ngModel', 
       replace : true 
        .... 
      }; 
     }); 

但是怎麼辦我將ngModel從language-picker傳遞給ui-select指令?

UPDATE

使用下面的建議,我得到了它的用戶界面,選擇工作,但外模式沒有得到所有更新,請參閱plnkr.co/edit/Y43dmMGIc5GxM9fLoNPW,可能是因爲它的子範圍和父範圍保持相同?

更新2

我得到了它在看起來可怕給我一個令人費解的方式工作,因爲我不知道爲什麼它「作品」擺在首位(見怪異的東西在發生控制器):

app.directive('languagePicker', function(LanguageService) { 
      return { 
       templateUrl : 'LanguagePickerTpl.html', 
       restrict : 'E', 
       scope : { 
        languages : '=' 
       }, 
       controller : function($scope, LanguageService) { 
        console.log($scope); 
        $scope.langs = LanguageService.get(); 
        $scope.model = $scope; 
       } 

      }; 
     }) 

模板:

<ui-select ng-model="model.languages" multiple search-enabled="true" 
    theme="select2" style="width: 300px;"> 
    <ui-select-match>{{$item.name}}</ui-select-match> 
    <ui-select-choices repeat="lang.id as lang in langs | filter: { name : $select.search }"> 
     <div ng-bind-html="lang.name | highlight: $select.search"></div> 
    </ui-select-choices> 
    </ui-select> 

我將非常高興,如果有人能解釋這是怎麼回事(以下簡稱 「工作」 EXA mple在這裏 http://plnkr.co/edit/B53F9sc7UGkj0uxUpC17

+0

如果我沒有弄錯,孩子的範圍可以在沒有做任何事情的情況下訪問父母的財產。如果你關心重用性,你應該遵循下面描述的答案,並通過子指令的屬性傳遞屬性。 – furier

回答

4

您需要在指令的作用域上使用「equals」語法。這將保持在父範圍內填充的值。 所以你的指令變爲:

app.directive('languagePicker', function() { 
     return { 
      template : '<ui-select ng-model="**PARENT'S NGMODEL**" multiple search-enabled="true" theme="select2" style="width: 300px;"><ui-select-match >{{$item.name}}</ui-select-match><ui-select-choices repeat="lang.id as lang in langs | filter: { name : $select.search }"><div ng-bind-html="lang.name | highlight: $select.search"></div></ui-select-choices></ui-select>', 
      restrict : 'E', 
      require : 'ngModel', 
      replace : true, 
      scope: { 
       ngModel: "=ngModel" 
      } 
      ... 
     }; 
    }); 

我相信這會爲你工作:) 讓我知道,如果它不!

+1

謝謝,它的工作原理!至少它可以在模板中使用嵌入的'。使用'ui-select',我不確定,因爲我現在遇到'multidir'錯誤,因爲我將兩個指令與隔離範圍結合在一起,所以還有更多工作要做) – AunAun

+0

其實我無法做到它使用'ui-select',外部模型根本不會更新,請參閱http://plnkr.co/edit/Y43dmMGIc5GxM9fLoNPW – AunAun

+2

我以非常複雜的方式工作,我不知道爲什麼它的作品http://plnkr.co/edit/B53F9sc7UGkj0uxUpC17 – AunAun

0

您可以通過model.selectedLanguages作爲一個屬性的指令,如:

< language-picker language="model.selectedLanguage" />

而且該指令中使用的語言屬性。 您可以決定您需要的範圍。

我也建議使用templateUrl將html代碼放入其中。它真的讓生活變得更容易。 然後你可以修改html文檔,按照建議編輯你的指令後簡單地放入ng-model =「language」。

官方文檔中確實有很多例子。 https://docs.angularjs.org/guide/directive

13

ng-model有一些特殊處理,請參閱here標題下的「自定義控制示例」。步驟是:

  1. 我建議你使用獨立的範圍;它使組件的界面更清晰,並且避免了副作用。在這種情況下,你想傳遞的可用選項(語言)列表:

    scope: { 
        langs: '=' 
    } 
    

    用法是:

    <language-picker ng-model="model.selectedLanguages" langs="langs"/> 
    
  2. 你的指令要求(也許可選)ngModel

    require: ['ngModel'] 
    
  3. 您覆蓋ngModel$render方法,例如:

    link: function(scope,elem,attrs,ctrls) { 
        var ngModelCtrl = ctrls[0]; 
        ngModelCtrl.$render = function() { 
         ... 
        }; 
    } 
    

    渲染的邏輯負責模型值(一個位置:<language-picker ng-model="model.selectedLanguages"/>,即model.selectedLanguages)傳送到視圖。我能想到的最簡單的事情,是使用隔離範圍轉移外模型值的隔離範圍的變量爲:

    ngModelCtrl.$render = function() { 
         scope.innerSelection = ngModelCtrl.$viewValue; 
        }; 
    

    綁定這個變量的模板:

    <ui-select ng-model="innerSelection" ...> 
        ... 
    </ui-select> 
    
  4. 最後,你必須確保更改內側選擇將傳播到外部模型:

    // still inside link() 
        scope.$watch('innerSelection', function(newval, oldval) { 
         if(newval != oldval) { // skip the first time 
          ngModelCtrl.$setViewValue(newval); 
         } 
        }); 
    

該解決方案可能比其他解決方案涉及更多一點,但可讓您使用ngModel的所有功能,例如,驗證,解析/格式化(即數據轉換)。

+0

'NgModelController。$ render()'是我最後一個缺失的難題。謝謝! –