angularjs - 难以替换" $ scope"用"这个"和类似的

时间:2014-09-03 13:28:45

标签: angularjs

根据有关该主题的几个教程,我试图在我的角度应用程序中略微减少$scope的混乱。一篇这样的文章演示了清理$scope的一个好策略,就是说我的控制器'classes',可以这么说。像这样;

//Don't do this
app.controller('MyCtrl', function($scope){
  $scope.doStuff = function(){
    //Really long function body
  };
});

//Do this instead
var MyCtrl = function($scope){
  var _this = this;

  _this.doStuff = function(){
    _this.doStuff();
  };
};

我正在尝试这样做,但遇到了很多麻烦 - 因为_this附加的代码完全与附加到$scope的代码完全不同。例如;

var editor = function($scope){
   var _this = this;

   _this.Model = {
      Id: null,
      Editing: false
   };

   _this.options = {
      columns : [
         { field: "Id", width: 25, title: "Identity" },
         { field: "Name", width: 40, title: "Name" }
      ]
   };
};

然后尝试在指令中使用它......

var gridDirective = function($parse) {
   return {
      restrict: 'A',
      scope: true,
      link: function(scope, element, attributes, controller) {
         // I expected this line to output the array I made, but it comes up undefined
         console.log('scope.options: ', scope.options);
      }
   }
};

我希望我指定给_this的对象在指令中的scope上可用,但这不会发生。只有当我直接将它们明确地分配给$scope时,我才能看到它们出现在指令中。

这有什么解决方案吗?或者我只需要在任何地方使用$scope吗?

3 个答案:

答案 0 :(得分:1)

$scope需要设置为_this而不是thisthis到控制器级别的本地var。

快速示例演示:

app.controller('MainController', function(){
  var vm = this;
  vm. error = '';
  vm.onUserComplete = function(response){
    console.log(vm.error);
  };

});

John Papa推荐了一种方法,您可以使用this创建控制器方法。但是,我个人确实看到了偏离标准的好处,但是如果你想了解更多关于这种方法的内容,那么就是解释它的文章:

http://www.johnpapa.net/angularjss-controller-as-and-the-vm-variable/

答案 1 :(得分:1)

在您的情况下,如果您希望使用this代替$scope,请执行以下操作:

var editor = function($scope){
   var _this = $scope;

   _this.Model = {
      Id: null,
      Editing: false
   };

   _this.options = {
      columns : [
         { field: "Id", width: 25, title: "Identity" },
         { field: "Name", width: 40, title: "Name" }
      ]
   };
};

但这种做法没有意义。 文章建议是(在我看来也是)

控制器的

使用构造函数模式 这是什么意思?这有什么好处,你将拥有不能分配到范围的私有,你将拥有将由你的选择分配到范围的功能,这将使你的控制器更清洁。我认为这篇文章的例子不对,应该是这样的:

var MyCtrl = function($scope){
  var _this = this;

  $scope.doStuff = _this.doStuff;
};

MyCtrl.prototype.doStuff = function(){
  //Really long function body, also this bounded with scope
};

MyCtrl.prototype.anotherFunc= function(){
  //This is another function which not bounded to scope
};

更新

我想建议在本文中解释这个article解释为angularguide的风格指南。

答案 2 :(得分:1)

您可以在控制器上下文范围内的ng-controller 中作为 表示法提供的别名中访问这些属性。所以如果你像这样声明控制器:

ng-controller="EditorController as editor"

这意味着您可以访问$scope.editor属性中的编辑器属性。

<强> DEMO

Javscript

.controller('EditorController', function() {

    var _this = this;

   _this.Model = {
      Id: null,
      Editing: false
   };

   _this.options = {
      columns : [
         { field: "Id", width: 25, title: "Identity" },
         { field: "Name", width: 40, title: "Name" }
      ]
   };

})

.directive('grid', function($parse) {
    return {
        restrict: 'A',
        scope: true,
        link: function(scope, element, attributes) {
            // I expected this line to output the array 
            // I made, but it comes up undefined
            console.log(scope.editor.options);
        }
    }
});

HTML

<div ng-app="demo" ng-controller="EditorController as editor">
    <div grid></div>
</div>

<强>更新

由于您的指令已经使用隔离范围定义,因此最好使用定义属性并访问从其分配的对象,而不是从父作用域访问它们。

JAVASCRIPT

.directive('grid', function($parse) {
    return {
        restrict: 'A',
        scope: {
          options: '='
        },
        link: function(scope, element, attributes) {
            console.log(scope.options);
        }
    }
});

HTML

<div ng-app="demo" ng-controller="EditorController as editor">
    <div grid="editor.options"></div>
</div>

您可以在 $compile service 中详细了解隔离范围和指令。