【问题标题】:Binding Angular element to scope outside of a controller将 Angular 元素绑定到控制器外部的范围
【发布时间】:2014-04-10 14:02:02
【问题描述】:

仍在快速学习 AngularJS,下面是一个简单的测试示例,使用 ng-repeat 显示列表,最终会弹出一个窗口。


Fiddle

HTML:

<div class="container" ng-app="main">
    <div id="person-info"></div>
    <div id="people" ng-controller="PeopleController" ng-cloak>
        <div class="person" ng-repeat="person in people" ng-class-even="'even'">
            <a href="" ng-click="showPersonInfo()">( more )</a> <span>{{person.name}}</span>
        </div>
    </div>
</div>

JavaScript:

angular.module('main',[]);

// Main Model
var model = [];
for (var i=0,n=10; i<n; i++){
    model[model.length] = {'name': 'Person '+ i, 'description': 'Person ' + i + ' description'};
}

// Main Controller
function PeopleController ($scope) {
    $scope.people = model;

    $scope.showPersonInfo = function (){
        document.getElementById('person-info').innerHTML = this.person.description;
    };
}

Fiddle


上面有两个问题:

  1. 在点击控制器中使用 DOM 查找/操作感觉不对

  2. 与第一点相关,必须有更好的方法将控制器外部的元素绑定到范围内的模型。理想情况下,我想要一个类似于:&lt;div id="person-info"&gt;{{$scope.person.description}}&lt;/div&gt; 的答案,点击控制器只需要关注可能设置$scope.person 或其他一些事件处理。


自从我上次查看 Angular 以来,文档已经变得更好了,但我欢迎 cmets 来提高可读性或最佳/常见做法。例如,我可能会因为使用“main”作为应用程序名称而感到悲伤:)

【问题讨论】:

  • 看看我的回答......

标签: javascript angularjs angularjs-scope angularjs-ng-repeat


【解决方案1】:

如果您想访问 PeopleController 控制器范围之外的内容,如下所示,请使用$rootScope


外部控制器范围 (Working Demo)

html

<div class="container" ng-app="main">
     <div id="person-info">{{desc}}</div>
    <div id="people" ng-controller="PeopleController" ng-cloak>
        <div class="person" ng-repeat="person in people" ng-class-even="'even'">
            <a href="" ng-click="showPersonInfo(person.description)">( more )</a> <span>{{person.name}}</span>
        </div>
    </div>
</div>

脚本

angular.module('main',[]);
// Main Model
var model = [];
for (var i=0,n=10; i<n; i++){
    model[model.length] = {'name': 'Person '+ i, 'description': 'Person ' + i + ' description'};
}
// Main Controller
function PeopleController ($scope, $rootScope) {
    $scope.people = model;

    $scope.showPersonInfo = function (personDesc){
        $rootScope.desc=personDesc;
    };
}

内部控制器范围 (Working Demo)

我的建议是将&lt;div id="person-info"&gt;{{value}}&lt;/div&gt; 封装在您的控制器中PeopleController

html

<div class="container" ng-app="main">

    <div id="people" ng-controller="PeopleController" ng-cloak>
        <div id="person-info">{{desc}}</div>
        <div class="person" ng-repeat="person in people" ng-class-even="'even'">
            <a href="" ng-click="showPersonInfo(person.description)">( more )</a> <span>{{person.name}}</span>
        </div>
    </div>

脚本

   angular.module('main',[]);

// Main Model
var model = [];
for (var i=0,n=10; i<n; i++){
    model[model.length] = {'name': 'Person '+ i, 'description': 'Person ' + i + ' description'};
}

// Main Controller
function PeopleController ($scope) {
    $scope.people = model;

    $scope.showPersonInfo = function (personDesc){
        $scope.desc=personDesc;
    };
}

【讨论】:

  • 感谢 Nidhish,我记得在最近的一次会议上看到了 $rootScope,但不记得它的名字了。
  • 我修改为将person 传递给点击处理程序并将其添加到$rootScope。令我惊讶的是,我不必克隆该对象——它似乎在我需要的持续时间内停留在范围/内存中。这让我可以在代码的其他地方更加明确;例如{{person.description}}{{description}} 更有意义。 =========================================== 我不太清楚目的是什么缓存angular.module() 是。我以为我可以在全局范围内使用 this 来引用范围内的对象,但我想不是。
【解决方案2】:

我给你一个建议:不要在控制器中使用元素方法,元素动作只允许在指令中。

关于您的代码: 我这样优化:

`<div class="container" ng-app="main" ng-controller="PeopleController">
  <div id="person-info">{{desc}}</div>
  <div id="people" ng-cloak>
    <div class="person" ng-repeat="person in people" ng-class-even="'even'">
        <a href="" ng-click="showPersonInfo(person)">( more )</a> <span>{{person.name}}</span>
    </div>
  </div>
</div>`

function PeopleController ($scope) {
  $scope.people = model;

  $scope.showPersonInfo = function (person){
    //console.log(person)
    $scope.desc = person.description;
  };
}

【讨论】:

  • 在控制器中使用元素方法,很难测试它(e2e)。
猜你喜欢
  • 2015-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多