简体   繁体   English

在AngularJS中使用JSON数组的嵌套控制器

[英]Nested Controllers that use JSON array in AngularJS

I wanted to have nested controllers like this... 我想拥有这样的嵌套控制器...

Controller 1 - This is the parent. 控制器1-这是父级。 It is populated from a JSON array that comes from a REST and uses ngRepeat. 它是从REST并使用ngRepeat的JSON数组填充的。

Controller 2 - This is the child. 控制器2-这是孩子。 It should get data from a REST call as well, but it needs to know which parent object it is under. 它也应该从REST调用中获取数据,但是它需要知道它在哪个父对象下。

Here's a visual... 这是视觉效果...

Parent 1
---Child 1
---Child 2
---Child 3
Parent 2
---Child 4
---Child 5
---Child 6

The children will be populated by calling a REST service and passing info about the parent. 将通过调用REST服务并传递有关父级的信息来填充子级。

Make sense? 说得通?

Here is some HTML that I have structured... 这是我构造的一些HTML ...

<div ng-app="App">
    <div ng-controller="spRisks">
        <table width="100%" cellpadding="10" cellspacing="2" class="employee-table">
            <tr ng-repeat="risk in Risks">
                <td>
                    <table width="100%" cellpadding="10" cellspacing="2" class="employee-table">
                        <tr id="{{risk.Id}}RiskDesc">
                            <td>{{risk.Risk_x0020_Description}}</td>
                        </tr>
                        <tr id="{{risk.Id}}RiskControls">
                            <td>
                                <div ng-controller="spControls">
                                    <table width="100%" cellpadding="10" cellspacing="2" class="employee-table">
                                        <tr ng-repeat="control in Controls">
                                            <td id="{{control.Id}}Control">{{control.Title}}</td>
                                            <td>
                                                <input type="radio" name="{{control.Id}}Answer" value="Yes">Yes
                                                <input type="radio" name="{{control.Id}}Answer" value="No">No
                                            </td>
                                            <td>
                                                <textarea id="{{control.Id}}Comment"></textarea>
                                            </td>
                                        </tr>
                                    </table>
                                </div>
                            </td>
                        </tr>
                    </table>
                </td>
            </tr>
        </table>
    </div>
</div>

And here is some code I have working that populates the parent controller... 这是我正在工作的填充父控制器的一些代码...

<script>
function getDataWithCaml(listName, caml) {
    var endpoint = "https://myteamsite.sharepoint.com//_api/web/lists/GetByTitle('" + listName + "')/GetItems(query=@v1)?@v1={\"ViewXml\":\"'" + caml + "'\"}";
    return jQuery.ajax({
        url: endpoint,
        method: "POST",
        headers: {
            "X-RequestDigest": $("#__REQUESTDIGEST").val(),
            "Accept": "application/json;odata=verbose",
            "Content-Type": "application/json;odata=verbose"
        }
    });
}

var App = angular.module('App', ['ngRoute'])
App.controller('spRisks', function ($scope, $http) {
    var caml = "<View><Query><Where><Eq><FieldRef Name='Owner'/><Value Type='Integer'><UserID/></Value></Eq></Where></Query></View>";
    var ownerData = getDataWithCaml("Owners", caml);
    ownerData.success(function (data) {
        var arrayOfExpressions = [];
        for (var i = 0; i < data.d.results.length; i++){
            arrayOfExpressions.push(CamlBuilder.Expression().LookupMultiField("Process_x0020_Owner_x0020_Title").EqualTo(data.d.results[i].Title));
        }
        var newCaml = new CamlBuilder().View().Query().Where().All(arrayOfExpressions).ToString();
        newCaml = newCaml.replace(/"/g, '\'');

        var jsonData = getDataWithCaml("Risks", newCaml);
        jsonData.success(function (jsonDataResults) {
            $scope.$apply(function(){$scope.Risks = jsonDataResults.d.results;});
        });
    });
});
function replaceAll(string, find, replace) {
  return string.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
</script>

One very cool thing that you should learn about angular is that if a controller is on a child element underneath another controller, then it inherits the values of the parent into its scope. 您应该学习的有关角度的一件很酷的事情是,如果某个控制器位于另一个控制器之下的子元素中,则它将父元素的值继承到其作用域中。 It does this through prototypal inheritance . 它通过原型继承来实现 This is worth reading up on, but it basically means that any changes you make to the child scope will not modify the parent scope, so you aren't going to corrupt anything (you can still call methods on the parent scope which can do corrupting for you. And I'm sure you can imagine other ways of interfering with the parent scope, but hopefully you see my point). 值得一读,但是基本上,这意味着您对子作用域所做的任何更改都不会修改父作用域,因此您不会破坏任何内容(您仍然可以在父作用域上调用可以破坏作用的方法我相信您可以想像其他干扰父级作用域的方法,但希望您能理解我的观点。 So if you have: 因此,如果您有:

<div ng-controller="Alpha">
   <div ng-controller="Beta"/>
   <div ng-controller="Beta"/>
   <div ng-controller="Beta"/>
</div>

Then you have three instances of the "Beta" controller, and all of them have a parent scope created by the function "Alpha." 然后,您具有“ Beta”控制器的三个实例,并且所有这些实例均具有由函数“ Alpha”创建的父范围。 So let's say you write the controller for alpha, like so: 因此,假设您为alpha编写控制器,如下所示:

function Alpha($scope) {
   $scope.title = "Snow White and the Seven Dwarves";
   $scope.dwarves = ['Sleepy','Sneezy','Dopey','Bashful',
     'Grumpy','Doc','Happy'];
}

Then, in all three instances of "Beta", you gain access to that parent: 然后,在“ Beta”的所有三个实例中,您都可以访问该父级:

function Beta($scope) {
  // This will write out "Snow White and the Seven Dwarves".
  console.log($scope.title);
}

Now, Beta can always manipulate title, and within its own scope, title will change without affecting the other siblings. 现在,Beta可以随时操纵标题,并且标题将在其自身范围内更改而不会影响其他同级物品。 If it added a dwarf to the collection, though, then.. well... another dwarf would appear. 但是,如果它在集合中添加了一个小矮人,那么.....另一个矮人将会出现。

ng-repeat is an easy way to create lots of child scopes and then initialize each with a variable: ng-repeat是创建大量子作用域,然后使用变量对其进行初始化的一种简便方法:

<div ng-controller="Alpha">
   <div ng-repeat="dwarf in dwarves"/>
</div>

So each repeated div tag has its own child scope with the variable dwarf already set. 因此,每个重复的div标签都有其自己的子范围,并且已经设置了dwarf变量。 It also has access to the title and even the dwarves collection. 它也可以访问title甚至是dwarves集合。

Neat. 整齐。

You can also attach to it another controller: 您还可以将另一个控制器附加到它:

<div ng-controller="Alpha">
   <div ng-controller="Beta" ng-repeat="dwarf in dwarves"/>
</div>

In which case, in addition to access to dwarf , dwarves , and title , it also runs the function Beta() in order to initialize whatever it needs to initialize. 在这种情况下,除了可以访问dwarfdwarvestitle ,它还运行函数Beta()来初始化需要初始化的内容。

I've attached a jsfiddle for you, so you can play around with a simple example: https://jsfiddle.net/p6e0wr1y/ 我为您附上了一个jsfiddle,因此您可以使用一个简单的示例: https ://jsfiddle.net/p6e0wr1y/

I hope this helps with your specific implementation. 希望这对您的具体实施有所帮助。 If you need me to address your stuff specifically, I will, but I'd like this answer to be valuable to anyone who finds themselves in a similar predicament. 如果您需要我专门解决您的问题,我会的,但是我希望这个答案对发现自己处在类似困境中的任何人都是有价值的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM