简体   繁体   English

AngularJS控制器和指令范围问题

[英]AngularJS Controller and Directive scope issues

I have been continuing to study angularjs for the past couple of days, especially about directives. 在过去的几天里,我一直在继续学习angularjs,尤其是在指令方面。

I have a scenario in which I have to load a list of records, with each one of them belonging to a category (5 categories in a drop-down select box). 我有一种情况,我必须加载一个记录列表,其中每个记录都属于一个类别(下拉选择框中的5个类别)。 I have created a directive to handle the "change" event for each one of them and made it so that their scopes do not overlap. 我创建了一个指令来处理它们中的每一个的“更改”事件,并使它的作用域不重叠。 As you can see on the console logs, each time you select an item from the drop-down, it is independent of the others. 从控制台日志中可以看到,每次从下拉列表中选择一个项目时,该项目都是独立的。

I have two questions: 我有两个问题:

  1. How do I load the categories ONLY ONCE from an outside resource. 如何仅从外部资源一次加载类别。 To be more specific, I only want to call practiceFactory.getCategories() only once. 更具体地说,我只想调用一次PracticeFactory.getCategories()。

  2. Is my code structure on the right track in regards to angular? 关于角度,我的代码结构是否正确?

Here's my html: 这是我的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>

Here's my js: 这是我的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);
                })
        }
    }
});

Here is a jsfiddle. 这是一个jsfiddle。 http://jsfiddle.net/j45fN/ http://jsfiddle.net/j45fN/

Going to answer your questions backwards... 向后回答您的问题...

In response to #2, I don't recommend using a factory to load data in your directive. 针对#2,我不建议您使用工厂将数据加载到您的指令中。 That sort of logic should take place in your module's controller (not in any directive's controller). 这种逻辑应该在模块的控制器中发生(而不是在任何指令的控制器中)。 In that regard, the other factory calls should be removed from your directive as well. 在这方面,其他工厂调用也应从指令中删除。

If you do that, it makes #1 easier -- you can simply call practiceFactory.getCategories once in practiceAppController and pass the result to your directive's scope using a bi-directional binding ( scope: { categories: '=' } ). 如果你这样做,它使#1更容易-你可以简单地调用practiceFactory.getCategories在一次practiceAppController和使用双向绑定(结果传递给你的指令的作用域scope: { categories: '=' }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM