【问题标题】:Calling an AngularJS function from outside the scope of an Angular App从 Angular 应用程序范围之外调用 AngularJS 函数
【发布时间】:2015-11-24 04:57:21
【问题描述】:

我已经看到很多与此问题相关的问题,但我尝试过的解决方案都没有奏效:

在 public 文件夹中,我有一个名为 app.js 的文件,我在其中定义了我的 AngularJS 应用程序,如下所示:

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

app.controller('MainCtrl', function($scope, $http) {

在文件的最后,我执行如下引导:

angular.bootstrap(document.getElementById('body'), ["app"]);

然后,在同一个文件夹和 HTML 中,我应用 AngularJS 的入口点是这样的:

 <div id="body">
<div ng-controller="MainCtrl">
    <div class="col-sm-6 col-md-6 col-lg-6" style="background-color: #D2D7D3">

        <div style="padding:25px;">

然后,在另一个文件夹中,我有另一个 JS 文件,我需要在其中调用 AngularJS 代码中定义的特定函数。该函数称为 Draw(),当我单击 AngularJS 按钮时会触发它。

要简单地调用另一个文件中的函数而不点击任何按钮,我正在做这样的事情:

        var e = document.getElementById('body');
        var scope = angular.element(e).scope();
// update the model with a wrap in $apply(fn) which will refresh the view for us
        scope.$apply(function() {
            scope.Draw(NumQuest);
        });
        //fim

编辑: 为了让我的问题更清楚一点,我可以添加更多细节:

我只需要一个控制器和一个模块来控制我的整个应用程序,因为所需的所有操作(即调用 3 个更新 SVG 图片的函数)都是相对独立的,所以我认为没有任何需要增加客户端代码的复杂性,这只会让我和其他与我一起工作的人感到困惑。

回忆我需要什么:

在单个应用程序中,使用一个控制器,我有一个函数 Draw(someInputValue),它可以生成一个 SVG 图形。正在从文本输入框接收此函数的输入。

在另一个文件上,当我单击另一个文本框时会执行 JS 操作(例如,显示警报或创建附加文本框)。我想要的是在单击文本框时将调用关联到 Draw(input) 。

也就是说,我想模拟当我单击从文本框中读取数字并执行一些操作的按钮时的行为,但是,我不想在文本框中手动引入输入并单击一个按钮,我想简单地点击一个文本框并执行相同的操作。

【问题讨论】:

  • 不得不求助于通过 DOM 元素获取角度范围是一种代码味道,您可能没有正确使用角度。这种架构是否有特定原因(即为什么这个其他文件不是角度组件)?
  • 添加评论并投票给@doldt。了解代码异味是一种很好的做法。通常,当某些事情真的很难解决时,它超出了通用设计原则,并且应该非常小心地采取这条路线。不能强调这一点,因此需要额外的评论。对于本主题的未来读者,请解释一下为什么您真的需要这个?没有其他设计解决方案?
  • 你想在这里完成什么,使用 Angular 来“不使用 Angular”?
  • @all,关于项目结构,我自己做这个项目,在朋友的帮助下,我们俩在Web应用程序方面都有点缺乏经验,这就是为什么我用了这么多。它可能不是最好的,但它只需要工作,由少数人在封闭环境中使用,其他人将永远不会使用该应用程序。我愿意学习正确的方法,但目前我只想要并且需要原型来工作
  • 另外,那种“臭”的代码只能用于单一的特定功能,在应用程序的其他任何地方都没有,独立于其他一切。

标签: javascript angularjs


【解决方案1】:

HTML

<div id="YourElementId" ng-app='MyModule' ng-controller="MyController">
  Hi
</div>

JS 代码

angular.module('MyModule', [])
    .controller('MyController', function ($scope) {
    $scope.myfunction = function (data) {
        alert("---" + data);
    };
});

window.onload = function () {
    angular.element(document.getElementById('YourElementId')).scope().myfunction('test');
}

【讨论】:

    【解决方案2】:

    我相信Understanding Angular’s $scope and $rootScope event system $emit, $broadcast and $on 可以帮助解决这个问题。

    如您所见,如果您使用$scope.$emit,它将触发一个事件直到$scope,从那以后,如果您使用$scope.$broadcast,则会触发该事件。

    最后使用$scope.$on 是您监听这些事件的方式。

    您可以通过下一个示例更好地理解:

    // firing an event upwards
    $scope.$emit('myCustomEvent', 'Data to send');
    
    // firing an event downwards
    $scope.$broadcast('myCustomEvent', {
      someProp: 'Sending you an Object!' // send whatever you want
    });
    
    // listen for the event in the relevant $scope
    $scope.$on('myCustomEvent', function (event, data) {
      console.log(data); // 'Data to send'
    });
    

    【讨论】:

    • angular.bootstrap() 与 bootstrap.js 无关。
    • 即使在编辑之后,您仍然在此问题中引用 bootstrap.js,但此问题与此无关。另外,这个问题与角度的事件系统没有任何关系。总的来说,这个答案正在解决一个不同的问题,并且参考其他框架,它并不是这个问题的真正答案。
    【解决方案3】:

    在这种情况下,您可能希望使用 $broadcast 来传递您的消息/数据,并使用 $on 来执行操作。

    但是,这种做法应该受到限制,并且应该明智地使用,以确保您在未来不会有明显的表现受到影响。

    Working with $scope.$emit and $scope.$on

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多