0

在过去的几天里,我一直在继续研究 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/

4

1 回答 1

0

想反着回答你的问题...

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

如果你这样做,它会使#1 变得更容易——你可以简单地调用practiceFactory.getCategories一次practiceAppController并使用双向绑定 ( scope: { categories: '=' }) 将结果传递到指令的范围。

于 2013-05-26T18:53:30.710 回答