使用AngularJS,如何匹配两个单独的ng-repeats中的项目?

时间:2018-01-11 17:01:27

标签: angularjs

使用AngularJS,我正在创建一个用两个Web请求提取数据的表。 每个网络请求都在HTML ng-repeat="user in users"ng-repeat="app in apps"中拥有自己的ng-repeat。现在,所有现有应用都会在user的每次重复中显示。我想做的是某种匹配,查找或过滤,只显示与用户相关联的应用。所以,当user.Title == app.Title

这是HTML:

<div ng-app="myApp">
  <div ng-controller="MainCtrl">

    <div class="ProfileSheet" ng-repeat="user in users">
      <h3 class="heading">User Profile</h3>
      <table id="Profile">
        <tr>
          <th>User</th>
          <td>{{user.Title}}</td>
        </tr>
        <tr>
          <th>First Name</th>
          <td>{{user.FirstName}}</td>
        </tr>
        <tr>
          <th>Last Name</th>
          <td>{{user.LastName}}</td>
        </tr>
        <tr>
          <th>Job Title</th>
          <td>{{user.JobTitle}}</td>
        </tr>
        <tr>
          <th>Emp ID</th>
          <td>{{user.EmployeeID}}</td>
        </tr>
        <tr>
          <th>Officer Code</th>
          <td>{{user.OfficerCode}}</td>
        </tr>
        <tr>
          <th>Email</th>
          <td>{{user.Email}}</td>
        </tr>
        <tr>
          <th>Telephone</th>
          <td>{{user.WorkPhone}}</td>
        </tr>
        <tr>
          <th>Fax Number</th>
          <td>{{user.WorkFax}}</td>
        </tr>
        <tr>
          <th>Location Description</th>
          <td>{{user.LocationDescription}}</td>
        </tr>
        <tr>
          <th>Mailstop / Banking Center #</th>
          <td>{{user.Mailstop}}</td>
        </tr>
      </table>
      <br>

      <h3 class="heading">User Applications</h3>
      <div style="border:3px solid #707070; padding-right:12px;">
      <h4 style="padding-left:5px;">User Applications</h4>
      <table id="Apps">
        <tr id="AppsHeading">
          <th>Application</th>
          <th>User ID</th>
          <th>Initial Password</th>
          <th>Options / Comment</th>
          <th>Setup Status</th>
        </tr>
        <tr ng-repeat="app in apps">
          <td>{{app.Application.Title}}</td>
          <td>{{app.Title}}</td>
          <td>{{app.InitialPassword}}</td>
          <td>{{app.OptionsComments}}</td>
          <td style="border-right:3px solid #707070;">{{app.SetupStatus}}</td>
        </tr>
      </table>
      </div>

  </div>
</div>

JS:

var app = angular.module('myApp', ['ngSanitize']);
var basePath = "https://portal.oldnational.com/corporate/projecthub/anchormn/associates"
app.controller('MainCtrl', function($scope, $http, $q){
    var supportList;
  $(document).ready(function() {
    $scope.getAdminList();
        $scope.getAppsList();
  });

    // $scope.selectedIdx = -1;
    // $scope.showResults = false
    $scope.prepContext = function(url,listname,query){
        var path = url + "/_api/web/lists/getbytitle('" + listname + "')/items" + query;
        console.log(path);
        return path;
    }
    $scope.getAdminList = function() {
    supportList = $http({
      method: 'GET',
      url: this.prepContext(siteOrigin+"/corporate/projecthub/anchormn/associates","User Administration","?$orderBy=LastName"),
      headers: {
        "Accept": "application/json; odata=verbose"
      }
    }).then(function(data) {
      //$("#articleSection").fadeIn(2000);
      console.log("adminlist", data.data.d.results);
      $scope.users = data.data.d.results;
    });
  };

    $scope.getAppsList = function() {
    supportList = $http({
      method: 'GET',
      // url: this.prepContext(siteOrigin+"/corporate/projecthub/anchormn/associates","User Applications","?$select=Title,InitialPassword,OptionsComments,SetupStatus,Application/Title&$orderBy=Application&$expand=Application"),
            url: this.prepContext(siteOrigin+"/corporate/projecthub/anchormn/associates","User Applications","?$select=Title,InitialPassword,OptionsComments,SetupStatus,Application/Title,ParentUserLink/ID&$orderBy=Application&$expand=Application,ParentUserLink"),
      headers: {
        "Accept": "application/json; odata=verbose"
      }
    }).then(function(data) {
      //$("#articleSection").fadeIn(2000);
      console.log("appslist", data.data.d.results);
      $scope.apps = data.data.d.results;
    });
  };
});
app.config([
    '$compileProvider',
    function($compileProvider){
        $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrom-extension|javascript):/)
    }
]);

我该怎么做?

1 个答案:

答案 0 :(得分:1)

控制器中有很多无关的代码。出于这个答案的目的,我删除了它。此外,我了解用户和应用程序与名为Title的属性相关,但名称让我感到困惑 - 如果数据没有意义,请原谅我。

建议:仅在必要时使用$(jQuery)。 Angular提供了许多替代jQuery功能的功能。而不是像$.ready那样使用:

$(document).ready(function() {
    $scope.getAdminList();
    $scope.getAppsList();
});

等待使用以下代码启动应用程序直到文档准备就绪:

(function () {
    angular.element(document).ready(function () {
        angular.bootstrap(document, ['myApp']);
    });
})();

然后您不必为控制器负担,而是负责等待文档加载。 注意:ng-app已从标记中删除。

建议:使用$q.all()等待多个承诺解决。 $q.all()会等到所有承诺决定致电.then()。这有助于确保在您开始使用它时所有数据都可用。

建议:如果视图将使用属性和功能,则仅将其分配给$scope。我删除了$scope对象中视图未使用的函数。

它是如何运作的?

当控制器加载时,我们使用$q.all()来调用并等待fetchAdminList()fetchAppsList()从API获取数据。每个API请求解析后,我们将.then()回调中的数据打开并返回(有关promise链接的更多信息,以了解从.then()返回值时会发生什么)。当两个promise都解决后,我们将数据存储在$scope上,以使其可供视图使用。我们还预先计算每个用户可以使用的应用程序,并将这些数据存储在$scope.userApps中,以使其可供视图使用。

我无法访问您从中获取数据的API。我使用$http和静态数据立即解决了$q.resolve()次调用。准备就绪后,只需将$q.resolve(...)替换为获取功能中的原始$http(...)来电。

运行代码段以查看其实际效果。

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

(function () {
    angular.element(document).ready(function () {
        angular.bootstrap(document, ['myApp']);
    });
})();

var USERS = [
    {
        Title: 'Software Engineer',
        FirstName: 'C',
        LastName: 'Foster',
        EmployeeID: 1
    },
    {
        Title: 'Software Engineer',
        FirstName: 'J',
        LastName: 'Hawkins',
        EmployeeID: 2
    },
    {
        Title: 'CEO',
        FirstName: 'Somebody',
        LastName: 'Else',
        EmployeeID: 3
    }
];

var APPS = [
    {
        Application: { Title: 'StackOverflow' },
        Title: 'Software Engineer'
    },
    {
        Application: { Title: 'Chrome' },
        Title: 'Software Engineer'
    },
    {
        Application: { Title: 'QuickBooks' },
        Title: 'CEO'
    }
]

app.controller('MainCtrl', function ($scope, $http, $q) {
    $q.all({
            users: fetchAdminList(),
            apps: fetchAppsList()
        })
        .then(function(result) {
            // Store results on $scope
            $scope.users = result.users;
            $scope.apps = result.apps;

            // Pre-compute user apps
            $scope.userApps = $scope.users.reduce(
                function(userApps, user) {
                    userApps[user.EmployeeID] = getUserApps(user.Title);
                    return userApps;
                },
                []
            );
        });

    function fetchAdminList() {
        return $q.resolve({ data: { d: { results: USERS } } })
            .then(function (data) { return data.data.d.results; });
    }

    function fetchAppsList() {
        return $q.resolve({ data: { d: { results: APPS } } })
            .then(function (data) { return data.data.d.results; });
    }

    // Get a list of apps that apply to user title
    function getUserApps(userTitle) {
        return $scope.apps.filter(function(app) {
            return app.Title === userTitle;
        });
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.js"></script>

<div>
    <div ng-controller="MainCtrl">

        <div class="ProfileSheet" ng-repeat="user in users">
            <h3 class="heading">User Profile</h3>
            <table id="Profile">
                <tr>
                    <th>User</th>
                    <td>{{user.Title}}</td>
                </tr>
                <tr>
                    <th>First Name</th>
                    <td>{{user.FirstName}}</td>
                </tr>
                <tr>
                    <th>Last Name</th>
                    <td>{{user.LastName}}</td>
                </tr>
                <tr>
                    <th>Job Title</th>
                    <td>{{user.JobTitle}}</td>
                </tr>
                <tr>
                    <th>Emp ID</th>
                    <td>{{user.EmployeeID}}</td>
                </tr>
                <tr>
                    <th>Officer Code</th>
                    <td>{{user.OfficerCode}}</td>
                </tr>
                <tr>
                    <th>Email</th>
                    <td>{{user.Email}}</td>
                </tr>
                <tr>
                    <th>Telephone</th>
                    <td>{{user.WorkPhone}}</td>
                </tr>
                <tr>
                    <th>Fax Number</th>
                    <td>{{user.WorkFax}}</td>
                </tr>
                <tr>
                    <th>Location Description</th>
                    <td>{{user.LocationDescription}}</td>
                </tr>
                <tr>
                    <th>Mailstop / Banking Center #</th>
                    <td>{{user.Mailstop}}</td>
                </tr>
            </table>
            <br>

            <h3 class="heading">User Applications</h3>
            <div style="border:3px solid #707070; padding-right:12px;">
                <h4 style="padding-left:5px;">User Applications</h4>
                <table id="Apps">
                    <tr id="AppsHeading">
                        <th>Application</th>
                        <th>User ID</th>
                        <th>Initial Password</th>
                        <th>Options / Comment</th>
                        <th>Setup Status</th>
                    </tr>
                    <tr ng-repeat="app in userApps[user.EmployeeID]">
                        <td>{{app.Application.Title}}</td>
                        <td>{{app.Title}}</td>
                        <td>{{app.InitialPassword}}</td>
                        <td>{{app.OptionsComments}}</td>
                        <td style="border-right:3px solid #707070;">{{app.SetupStatus}}</td>
                    </tr>
                </table>
            </div>

        </div>
    </div>