angularjs - 在 Controller 函数之外的脚本中读取 AngularJS 表达式

由于 this thread 中的以下引用

The best practice is never use JQuery or angular.element() for DOM manipulation inside controllers. Controllers are only used for our business logic.

我已经移动了一个调用 CodeMirrorJQuery 的大函数到 Controller 之外。 big 函数用于合并两个文本区域的内容。 JSBin

HTML:

<div ng-app="myApp" ng-controller="myCtrl">
  <textarea ng-model="area1">area1</textarea>
  <textarea ng-model="area2">area2</textarea>
  <div>First: {{area1}}, {{area2}}</div>
  <div id="output"></div>
  <script>
    function bigfunction(area1, area2) {
      // a big function, the following is for the sake of simplicity
      return "Second: " + area1 + ", " + area2
    }
    var output = bigfunction({{area1}}, {{area2}});
    $("#output").html(output)
  </script>
</div>

Javascript:

var app = angular.module('myApp', []);

app.controller('myCtrl', function($scope) {
    $scope.area1 = "initial textarea1";
    $scope.area2 = "initial textarea2"
});

有谁知道为什么无法识别脚本中的 {{area1}}{{area2}}

最佳答案

问题是您将 JavaScript 与 AngularJS 模板混合在一起。

var output = bigfunction({{area1}}, {{area2}});

您不能期望内联 JavaScript 可以使用 AngularJS 模板工作。下面是发生的事情:加载 HTML 文件(模板)并解析和执行内联 JS。它失败是因为它包含错误的语法 ({{area1}})。这甚至发生在 AngularJS 加载之前。此外,JavaScript 代码只被求值一次,因此即使模板实际上用字符串替换了 {{area1}},代码也不会被重新求值,也不会产生不同的输出。您将需要完全改变您的方法。

我猜您想在 Controller 外部执行两个作用域变量的连接,并可能向其添加额外的逻辑。您可以将代码移动到服务中,然后在您的 Controller 中使用它,或者使用指令(我不知道您的确切用例,所以我很难说哪种方法更有意义)。

由于您描述的是两个模型值的简单串联,指令似乎很有意义。您的 HTML 可能如下所示:

<div ng-app="myApp" ng-controller="myCtrl">
    <textarea ng-model="area1">area1</textarea>
    <textarea ng-model="area2">area2</textarea>
    <div>First: {{area1}}, {{area2}}</div>
    <output area1="area1" area2="area2"></output>
</div>

然后在 JS 中,添加这个简单的指令:

app.directive('output', function() {
    return {
        restrict: 'E',
        template: '<div id="output">Second: {{area1}}, {{area2}}</div>',
        scope: {
            area1: "=",
            area2: "="
        }
    };
});

如果出于某种原因你希望向你的指令添加额外的逻辑,你总是可以在链接函数中这样做。

如果您要添加服务,HTML 将再次只需要一个小改动:

<div ng-app="myApp" ng-controller="myCtrl">
    <textarea ng-model="area1">area1</textarea>
    <textarea ng-model="area2">area2</textarea>
    <div>First: {{area1}}, {{area2}}</div>
    <div>{{output}}</div>
</div>

JS 可能看起来像这样:

app.controller('myCtrl', function($scope, joiner) {
    $scope.area1 = "initial textarea1";
    $scope.area2 = "initial textarea2";
    $scope.$watchGroup(["area1", "area2"], function() {
        $scope.output = joiner.join($scope.area1, $scope.area2);
    });
});
app.service('joiner', function() {
    this.join = function(a1, a2) {
        return "Second: " + a1 + ", " + a2;
    };
});

该服务可以包含您需要的任何逻辑。

https://stackoverflow.com/questions/41342158/

相关文章:

cherrypy - 更改 Content-Type 后返回的内容未自动编码

apache-spark - 自定义 log4j 类不适用于 spark 2.0 EMR

wpf - 在其 winforms 父级中拖动托管 WPF 控件吞噬的事件

compiler-construction - 这个产生式规则是否左递归?

sprite-kit - SpriteKit : calculate distance betwee

hdf5 - dask 和并行 hdf5 写入

Ansible - 使用用户输入选择变量

apache-spark - Spark 溢出独立于分配的执行程序内存

C - do/while 循环和 switch(int)。输入 char 值会导致 inf。环形

android - 使用 DownloadManager.Request 从 url 下载文件时下载