【问题标题】:Simple Angular Directive简单的角度指令
【发布时间】:2013-10-17 15:58:44
【问题描述】:

我正在尝试编写我的第一个 Angular 指令来为我的应用程序添加分页功能。 我现在保持简单,并希望指令只共享控制器的范围。

在我的控制器中,我有一个名为:

$scope.pages

在我的指令的链接函数中,我可以这样做:

console.dir($scope)

查看控制器范围对象的内容,但如果我尝试访问 pages 属性,它会以未定义的形式返回。

我错过了什么?

提前致谢。

myDirectives.directive("mdPagination", function(){
    return {
        template: '',
        restrict: 'A',
        priority: 1000,
        scope: false,
        link: function($scope, el, attrs){
            console.dir($scope.pages);  //returns undefined
            el.text('hello world');
        },
    }
});

编辑:我知道那里有分页模块,但我的需求不大,我认为构建自己的模块是开始学习如何构建指令的简单方法。

【问题讨论】:

  • 尝试删除scope: false
  • 如何在你的控制器中填充 $scope.pages?通过 AJAX 请求?
  • 查看这些现有的AngularJS分页模块@ngmodules.org/modules?query=pagination
  • 我们能看到您设置$scope.pages 的控制器以及使用该控制器和您的指令的HTML 吗?
  • $scope.pages 何时填充到控制器中?如果它直接填充在控制器中,它对我有用。 p.s.在链接函数中,您不需要将其命名为 $scope,范围将是您作为第一个参数传递的任何内容,链接函数中的名称与控制器中的名称无关

标签: angularjs angularjs-directive


【解决方案1】:

您遇到的问题是指令链接函数在控制器之前运行,因此您通常无法在此链接阶段访问范围值。还有其他几种方法可以做到这一点。解决您的问题的最直接方法是使用$scope.$watch。所以这样的事情应该可以工作:

$scope.watch('pages', function(pages) {
  console.dir(pages);
});

这适用于丢失的情况。我还建议通过使用属性为您的手表传递表达式(基本上是属性名称),将您的控制器与它声明的范围解耦。一个简单的示例可能如下所示:

<div my-directive="myProperty">

link: function($scope, el, attrs) {
  $scope.watch(attrs.myDirective, function(value) {
   //do something you need to do with the value here
  });
}

但是,当您增加指令的复杂性时,您可能希望为指令提供自己的控制器来管理状态,而无需直接调用手表。这个控制器可以使用属于指令本身的子作用域scope: true,或者只使用父作用域scope: false。您的选择可能取决于需要。那么你可以:

myDirectives.directive("mdPagination", function(){
    return {
        template: '',
        restrict: 'A',
        priority: 1000,
        controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) {
             console.dir($scope.pages);

        }],
        link: function($scope, el, attrs){
          $element.text('hello world');
        }
    }
});

【讨论】:

    【解决方案2】:

    默认情况下,指令与控制器共享其范围。为此,您的对象中不得有“范围”属性,如下所示:

    myDirectives.directive("mdPagination", function(){
        return {
            template: '',
            restrict: 'A',
            priority: 1000,
            link: function($scope, el, attrs){
                console.dir($scope.pages);
                el.text('hello world');
            },
        }
    });
    

    【讨论】:

    • 范围属性与问题无关。您无法可靠地直接访问链接函数中的 $scope 值。您必须在其上附上手表。
    【解决方案3】:

    @Sandro 是对的。您将指令中的scope 属性设置为false,这意味着范围不会与控制器继承(或共享)其属性。如果您删除了错误,它应该可以按您的预期工作。

    有关如何使用$scope 的文档在这里:http://code.angularjs.org/1.2.0-rc.3/docs/api/ng.$rootScope.Scope

    创建指令的开发人员指南有很多关于如何设置指令的好信息,以便它为您提供所需的范围。这些文档在这里:http://code.angularjs.org/1.2.0-rc.3/docs/guide/directive

    希望对您有所帮助。

    【讨论】:

    • 不,如果您将范围设置为“真”,它会为指令创建一个单独的范围。 code.angularjs.org/1.2.0-rc.3/docs/guide/directive
    • 实际上它为继承的指令创建了一个子作用域,如果将其设置为 false,它使用直接声明它的当前作用域。公平地说,这是指令设计的一个相当混乱的方面。
    猜你喜欢
    • 2016-12-25
    • 1970-01-01
    • 1970-01-01
    • 2016-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-25
    • 1970-01-01
    相关资源
    最近更新 更多