从外面调用角度控制器的方法

时间:2014-10-16 10:18:49

标签: javascript angularjs angularjs-scope angularjs-controller

以下是代码:http://jsbin.com/rucatemujape/1/edit?html,js,console,output

我的问题是如何从JavaScript手动调用方法 changeUser 以便输出HTML更改?

我可以通过执行(依赖于jQuery)

来做到这一点
angular.element('body').scope().changeUser({fullName: 'John Doe'});
angular.element('body').scope().$apply()

但我想知道有更好的方法吗?

例如,在knockout.js中,我可以随时执行viewModel.someFunction()并且敲除正确处理此事。

为什么我要这样做:因为我希望能够在调试代码时从浏览器的控制台更改模型。

编辑:我需要它的另一个原因是它从Restful Services获取信息并更新模型。是的我可以通过单击带有" ng-click" 属性的按钮触发该事件,但是如何处理非用户启动的事件?例如,重复 setInterval 或其他内容

3 个答案:

答案 0 :(得分:2)



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

myApp.controller('MyController', function($scope, $timeout) {
  $scope.user = {};
  $scope.count = 0;

  $scope.changeUser = function(user) {
    $scope.user = "MyName";
    $scope.count++;

    // call function after 1 sec.
    $timeout($scope.changeUser, 1000);
  };

  // initiate function
  $scope.changeUser();
});

<!DOCTYPE html>
<html ng-app="myApp">
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js"></script>
</head>
<body ng-controller="MyController"
  <span>Hello, {{user}}</span>
  <span>count, {{count}}</span>
</body>
</html>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

使用ng-click =&#34;更改用户()&#34;调用函数

http://jsbin.com/rucatemujape/2/edit

答案 2 :(得分:1)

控制器并没有真正将“API”暴露在他们自己的“范围”之外(以及下面)。因此,要么在控制器中执行Ajax调用,要么公开“用户数据”以显示。

例如:Kostia Mololkin的答案(在主要评论中)使用全局变量来共享数据。

Angular Way

在这里,我提出了一种更“棱角分明的方式”:用户正在处理“服务”。不清楚你想要的方向。无论如何,这不会有害。

当您使用“数据”来“沟通状态”而不是“事件”时,Angular效果最佳。所以这个想法再次是安排事情,所以你的数据实例(即“用户”)在“{{user.fullname}}”和发生Ajax调用的地方之间是相同的。皮肤猫的方法有很多种,这在很大程度上取决于您的应用程序的需求。例如,如果你为ajax调用构建一个单例服务,你也可以拥有它所拥有的数据并以某种形式或者另一种形式暴露给控制器(再次,这样做的方法很多)。

注意:如果您使用angular的系统执行ajax调用(例如$ http或$ resource),那么您永远不需要手动调用“$ apply()”。顺便说一句,你应该用$ apply()来“包裹”调用,而不是“事后”调用它来正确处理“抛出”。

使用Ajax / Rest调用的Plunker示例:

http://plnkr.co/edit/SCF2XZCK5KQWkb4hZfOO?p=preview

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

myApp.factory('UserService', ['$http',function($http){

    // Extra parent object to keep as a shared object to 'simplify'
    // updating a child object
    var userData = {};

    userData.user = { fullName:'none' };

    function loadUserData(userid) {
      $http.get('restapi_getuserdata_'+userid+'.json').
        success(function(data, status, headers, config) {
          // update model
          userData.user = data;
        }).
        error(function(data, status, headers, config) {
          console.log("error: ", status);
        });
    }

    return {
      userData: userData,
      loadUserData: loadUserData
    };

}]);

myApp.controller('MyController', ['$scope', 'UserService', '$timeout', 
  function($scope, UserService, $timeout) {

    // shared object from the Service stored in the scope
    // there are many other ways, like using an accessor method that is 
    // "called" within the HTML  
    $scope.userData = UserService.userData;

}]);


myApp.controller('SomeOtherController', ['UserService', '$timeout', 
  function(UserService, $timeout) {

    // $timeout is only to simulate a transition within an app 
    // without relying on a "button".
    $timeout(function(){

      UserService.loadUserData(55);

    }, 1500);

}]);

HTML:

<html ng-app="myApp">
...
<body ng-controller="MyController">

  <span>Hello, {{userData.user.fullName}}</span>

  <!-- simulating another active piece of code within the App -->
  <div ng-controller="SomeOtherController"></div>

...

使用getter方法而不是数据的变体:

http://plnkr.co/edit/0Y8gJolCAFYNBTGkbE5e?p=preview

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

myApp.factory('UserService', ['$http',function($http){

    var user;

    function loadUserData(userid) {
      $http.get('restapi_getuserdata_'+userid+'.json').
        success(function(data, status, headers, config) {
          console.log("loaded: ", data);
          // update model
          user = data;
        }).
        error(function(data, status, headers, config) {
          console.log("error: ", status);
          user = undefined;
        });
    }

    return {
      getCurrentUser: function() { 
        return user || { fullName:"<none>" };
      },
      userLoggedIn: function() { return !!user; },
      loadUserData: loadUserData
    };

}]);

myApp.controller('MyController', ['$scope', 'UserService', '$timeout', 
  function($scope, UserService, $timeout) {

    // getter method shared
    $scope.getCurrentUser = UserService.getCurrentUser;
}]);


myApp.controller('SomeOtherController', ['UserService', '$timeout', 
  function(UserService, $timeout) {

    // $timeout is only to simulate a transition within an app 
    // without relying on a "button".
    $timeout(function(){

      UserService.loadUserData(55);

    }, 1500);

}]);

HTML:

<html ng-app="myApp">
...
<body ng-controller="MyController">

  <span>Hello, {{ getCurrentUser().fullName }}</span>

  <!-- simulating another active piece of code within the App -->
  <div ng-controller="SomeOtherController"></div>

...