Angularjs 控制器内部指令的行为

Angularjs 控制器内部指令的行为,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我知道来自控制器的$scope可以共享给指令中的链接函数 例如,在这段代码中,我可以从声明的控制器调用函数,在浏览器控制台上打印“Hello World”: .directive('myDirective', [function () { return { restrict : 'E', replace : true, controller: 'MyController', temp

我知道来自
控制器的
$scope
可以共享给
指令中的链接函数

例如,在这段代码中,我可以从声明的控制器调用函数,在浏览器控制台上打印“Hello World”:

 .directive('myDirective', [function () {
        return {
            restrict : 'E',
            replace : true,
            controller: 'MyController',
            templateUrl : 'directives/myDirective.tpl.html',
            link : function (scope, elem, attrs, controller) {
                scope.message = 'Hello World!';
            }
        };
    }])

    .controller('MyController', [function ($scope, $element, $attrs, $log, $timeout) {

        // $timeout to wait the link function to be ready.
        $timeout(function () {
            // This prints Hello World as expected.
            $log.debug($scope.message);
         });


        });
    }])
好的,这个很好用

我的问题是

  • 在这种方法中,控制器和指令之间共享的是相同的范围
  • 使用这种方法的后果是什么?让我们假设我将操作
    controller
    中的
    DOM
    元素,仅在
    链接函数中操作
  • 我真的需要避免在这个
    控制器中操纵DOM元素
    ?即使
    $scope
    $elem
    等是相同的
  • 这些都是我没有发现的问题

    .

    参见更新的plunker:

  • 是的,这是相同的范围。id相同,您可以看到内容已更新
  • 共享范围的含义是很难追踪谁改变了什么。我强烈建议您的指令使用隔离作用域
  • 可以随意操作DOM。跟踪变化将是一个有趣的练习。。。我还强烈建议不要进行任何DOM操作。我会将DOM操作与其他活动分离,将它们封装在一个指令中
  • Angular的优点之一是指令,因此我会尽可能使用它们来分离您的关注点。

    1)是的,它们都共享相同的范围,因为您使用指令的控制器来记录范围,这意味着您可以像这样将“MyController”放在指令内部

    return {
      replace: true,
      controller: function($scope,...){ //  equals MyController
      }
    }
    
    如果控制器是指令的包装器,而不是在指令内部,并且指令范围设置为true或对象散列,则它们不会共享相同的范围

    2) 没有后果,只是不要操作控制器中的DOM,控制器的一个用途是将指令连接在一起,以便从服务或通过简单的范围扩展(即:scope.message=“Hello World”)获取或设置数据,这两种方式都需要最小化。如果您想在其他指令之间共享数据,您只需使用该指令的控制器即可

    3) 是的,避免控制器中的DOM操作,其不是用于表示逻辑或用户看到的内容,即指令的作用,记住SOC(关注点分离)MVC/MV*模式的每个部分都有自己的作用

    用一种简单的方式来思考它,就像这个用户在表示层上看到按钮,用户单击按钮在业务层(控制器)上单击按钮的功能,它获取结果并存储在数据/模型层中

    警告如果按钮除了处理用户和数据层之间的命令(计算、求值等)之外,还执行其他操作,例如添加函数属于指令内部的类(DOM操作)

    一个伟大的阅读和更深入

    在这种方法中,控制器和指令之间共享的范围相同

    是的

    使用这种方法的后果是什么?假设我不会在控制器中操作DOM元素,只在链接函数中操作

    控制器提供指令的行为,就像常规角度应用程序一样。也就是说,您应该只在控制器函数内操作作用域。如果需要更改link函数的作用域,请调用其方法。此外,由于控制器是在link函数之前执行的,因此您应该在前者中初始化作用域,以便后者可以获得一个有效的模型来处理

    我真的需要避免在这个控制器中操纵DOM元素吗?即使$scope、$elem等是相同的

    根据定义,link函数是执行DOM操作的地方。我找不到阻止您在指令的控制器内操作DOM的技术原因,除非您不应该这样做。事实上,为了检查我刚刚更改了一个指令,我已经编写了所有代码,并将它们从link函数移到controller函数,所有的代码都在工作。但如果将作用域逻辑和DOM操作混合在一起,我认为很难追踪到底发生了什么


    最后,您可能会发现本文很有用:。

    我建议您查看egghead指令视频。这些对我来说真的很有用@NuclearHost感谢您的评论。我已经看过几乎所有的书呆子视频。我今天也再次检查,以找到一些更新。。。但我不记得他对我在任何视频中问的问题说了什么=(它没有注销“Hello World”它记录下来了undefined@DavidChase我的错,因为控制器是在link函数之前实例化的,所以我需要在调用$log.debug之前使用timeout来确保调用了$compile函数。我会更新这个问题。所有的答案都是格式正确的,解释得很好。但我需要选择一个。感谢我没有读过的精彩文章然而(是的,我以前从未在gh上看过angular wiki,而且一直都在那里!),它对我很有帮助。@MichaelBenford您不将DOM操作放入控制器的原因是,它们用于通过只包含“业务逻辑”的方法进行范围对象初始化和范围对象扩充测试也变得非常困难。我想我已经说过了,换言之:)