AngularJS控制器和指令范围问题

时间:2013-05-26 18:15:51

标签: javascript angularjs

过去几天我一直在研究angularjs,特别是关于指令。

我有一个场景,我必须加载一个记录列表,每个记录都属于一个类别(下拉选择框中有5个类别)。我已经创建了一个指令来处理它们中的每一个的“更改”事件,并使它们的范围不重叠。正如您在控制台日志中看到的那样,每次从下拉列表中选择一个项目时,它都独立于其他项目。

我有两个问题:

  1. 如何仅从外部资源加载类别ONCE。至 更具体一点,我只想打电话 practiceFactory.getCategories()只有一次。

  2. 我的代码结构是否在关于angular?

  3. 的正确轨道上

    这是我的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/

1 个答案:

答案 0 :(得分:0)

向后回答你的问题......

作为对#2的回应,我不建议使用工厂在指令中加载数据。这种逻辑应该发生在模块的控制器中(而不是在任何指令的控制器中)。在这方面,其他工厂调用也应该从你的指令中删除。

如果你这样做,它会让#1更容易 - 你只需在practiceFactory.getCategories中调用practiceAppController一次,然后使用双向绑定将结果传递给你的指令范围({{1} })。