【问题标题】:Nested Controllers that use JSON array in AngularJS在 AngularJS 中使用 JSON 数组的嵌套控制器
【发布时间】:2015-04-30 01:08:44
【问题描述】:

我想要这样的嵌套控制器...

控制器 1 - 这是父级。它由来自 REST 并使用 ngRepeat 的 JSON 数组填充。

控制器 2 - 这是孩子。它也应该从 REST 调用中获取数据,但它需要知道它在哪个父对象下。

这是一个视觉...

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

将通过调用 REST 服务并传递有关父级的信息来填充子级。

有意义吗?

这是我构建的一些 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>

这是我正在处理的一些填充父控制器的代码...

<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>

【问题讨论】:

  • Make sense 不是一个真正的问题。你有什么具体问题?您的服务代码在哪里?一个指令也可能是实用的,但你真的没有提供很多工作
  • 我认为很明显我正在寻找有关如何构建它的指导。我没有任何工作。我需要帮助弄清楚如何去做。
  • 至少在 html 中创建一个模拟它需要做什么。也许您可以在第一个回调中发出辅助请求,然后简单地使用指令将数据传递给重复元素
  • 我添加了一些我现在拥有的代码,并添加了一些 HTML 用于我希望孩子们去的地方。
  • 而不是 ng-controller 作为子级,如果它是一个指令,则可以传递发出请求所需的父数据并在指令中使用相同的控制器。使用$http 而不是$.ajax 将使您的应用程序对角度更友好,因为$http 返回$q 角度中使用的承诺

标签: javascript json angularjs rest


【解决方案1】:

您应该了解有关 Angular 的一个非常酷的事情是,如果一个控制器位于另一个控制器下的子元素上,那么它将继承父级的值到其范围内。它通过prototypal inheritance 做到这一点。这值得一读,但它基本上意味着您对子范围所做的任何更改都不会修改父范围,因此您不会破坏任何东西(您仍然可以调用父范围上的方法来破坏为你我相信你可以想象其他干扰父范围的方式,但希望你能明白我的意思)。所以如果你有:

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

那么您就有了“Beta”控制器的三个实例,它们都有一个由“Alpha”函数创建的父作用域。因此,假设您为 alpha 编写控制器,如下所示:

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

然后,在所有三个“Beta”实例中,您都可以访问该父级:

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

现在,Beta 始终可以操纵标题,并且在它自己的范围内,标题会发生变化,而不会影响其他兄弟姐妹。但是,如果它在集合中添加了一个侏儒,那么......好吧......另一个侏儒会出现。

ng-repeat 是一种创建大量子作用域然后用变量初始化每个作用域的简单方法:

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

所以每个重复的div 标记都有自己的子范围,变量dwarf 已经设置。它还可以访问title 甚至dwarves 集合。

整洁。

你也可以附加另一个控制器:

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

在这种情况下,除了访问dwarfdwarvestitle之外,它还运行函数Beta()来初始化它需要初始化的任何东西。

我已经为你附上了一个 jsfiddle,所以你可以玩一个简单的例子: https://jsfiddle.net/p6e0wr1y/

我希望这对您的具体实施有所帮助。如果您需要我专门解决您的问题,我会,但我希望这个答案对任何发现自己处于类似困境的人都很有价值。

【讨论】:

  • 我认为我被挂断的地方是我应该如何调用父范围。如果我设置 $scope.Risks = jsonDataResults.d.results;那么如何引用该数据集中的数据呢? Risks.Id?
  • 我发现我可以使用 $scope.Risks 引用父对象,但这让我可以访问整个对象数组。如何获得对当前父级的引用?我如何知道我目前处于风险中的哪一个对象?
  • 找到了! $scope.Risks[$scope.$parent.$index].Id
  • 你好。我很高兴你得到它!或者,您应该能够将 Risk 对象直接收集到您的作用域中,这样您就不必弄乱 $index 了。如果您想将一些代码放入小提琴或 Plunkr,我不介意检查一下。但听起来你确实在路上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-21
相关资源
最近更新 更多