2013-05-26 72 views
0

過去幾天我一直在繼續研究angularjs,尤其是關於指令。AngularJS控制器和指令範圍問題

我有一個場景,我必須加載一個記錄列表,每個記錄屬於一個類別(5個類別在下拉選擇框中)。我已經創建了一個指令來處理它們中的每一個的「更改」事件,並使它們的範圍不重疊。正如您在控制檯日誌中所看到的,每次從下拉列表中選擇一個項目時,它都是獨立於其他項目的。

我有兩個問題:

  1. 如何從外部資源只有一次加載的類別。到 更具體一些,我只想調用 practiceFactory.getCategories()一次。

  2. 是我的代碼結構在正確的軌道方面?

這裏是我的html:

<div data-ng-app="practiceApp"> 
    <h1>practiceAppController</h1> 
    <div data-ng-controller="practiceAppController"> 
     <p><select data-when-changed="saveCategory({{selectedCategoryId}})" data-ng-model="selectedCategoryId" data-ng-options="category.id as category.name for category in categories"></select></p> 
     <p><select data-when-changed="saveCategory({{selectedCategoryId}})" data-ng-model="selectedCategoryId" data-ng-options="category.id as category.name for category in categories"></select></p> 
     <p><select data-when-changed="saveCategory({{selectedCategoryId}})" data-ng-model="selectedCategoryId" data-ng-options="category.id as category.name for category in categories"></select></p> 
     <p><select data-when-changed="saveCategory({{selectedCategoryId}})" data-ng-model="selectedCategoryId" data-ng-options="category.id as category.name for category in categories"></select></p> 
     <p><select data-when-changed="saveCategory({{selectedCategoryId}})" data-ng-model="selectedCategoryId" data-ng-options="category.id as category.name for category in categories"></select></p> 
    </div> 
</div> 

這裏是我的JS:

var practiceApp = angular.module('practiceApp', []); 

practiceApp.controller('practiceAppController', function($scope, practiceFactory) { 
}); 

practiceApp.factory('practiceFactory', function() { 
    var factory = {}; 

    factory.getCategories = function() { // async call here 
     console.log('getCategories() was called'); 
     var categories = [ 
      {id: 1, name: 'Food & Dining'}, 
      {id: 2, name: 'Hotel & Travel'}, 
      {id: 3, name: 'Shopping'}, 
      {id: 4, name: 'Health & Beauty'}, 
      {id: 5, name: 'Activities'} 
     ]; 
     return categories; 
    } 

    factory.getSelectedCategory = function() { // async call here 
     console.log('getSelectedCategory() was called'); 
     var selectedCategoryId = Math.floor((Math.random()*5)+1); 
     return selectedCategoryId; 
    } 

    return factory; 
}); 

practiceApp.directive('whenChanged', function(practiceFactory) { 
    return { 
     restrict: 'A', 
     scope: {}, 
     controller: function ($scope) { 
      $scope.selectedCategoryId = practiceFactory.getSelectedCategory(); 
      $scope.categories = practiceFactory.getCategories(); 

      $scope.saveCategory = function(categoryId) { 
       console.log(categoryId); 
      } 
     }, 
     link: function(scope, element, attribute) { 
       element.bind('change', function() { 
        scope.$apply(attribute.whenChanged); 
       }) 
     } 
    } 
}); 

這裏是一個的jsfiddle。 http://jsfiddle.net/j45fN/

回答

0

要倒退爲您解答...

在回答#2,我不建議使用工廠在你的指令來加載數據。這種邏輯應該發生在你的模塊的控制器中(不在任何指令的控制器中)。在這方面,其他工廠電話也應該從您的指令中刪除。

如果你這樣做,它使#1更容易 - 你可以簡單地在practiceAppController調用practiceFactory.getCategories一次,並使用結果傳遞給你的指令的範圍雙向綁定(scope: { categories: '=' })。

+0

謝謝你的回答。是的,我必須將數據加載到我的指令中才能解決我遇到的範圍問題。我已經按照您的建議嘗試過,但不知何故無法實現。下拉列表未被填充。如果您如此友善地編輯我上面的小提琴鏈接以顯示正確的方式?非常感謝你。 – lynkyle

+0

我想我不明白這個指令的必要性。這似乎是一個更乾淨的方式來做到這一點,除非我失蹤:something.http://jsfiddle.net/j45fN/1/ – Langdon

+0

哇!謝謝。爲了更多地瞭解指令,我忽略了一些簡單的事情,並開始重新發明輪子。只是一個後續問題,$ index是從哪裏來的? (.i.e。data-ng-model =「selectedCategories [$ index]」) – lynkyle