AngularJS - 如何从promise中呈现模板和数据

时间:2016-07-10 07:45:40

标签: javascript angularjs ajax

好吧,我是Angular的新手,过去两天都试图找到一个很好的方法来做到这一点并且失败了。我不确定标题是否也不错。

我正在尝试用菜单制作一个简单的页面。此人将单击菜单链接,然后菜单下方的视图应相应地呈现(当然不刷新整个页面)。听起来很简单。

但问题是,管理员的菜单和普通用户的菜单会有,所以菜单是通过ajax加载的。这是我得到的一个例子:

[
    {
        name: "Manage games",
        templateUrl: "/view/mygames.html",
        url: "/games",
    },
    {
        name: "Weekly Reports",
        templateUrl: "/view/myreports.html",
        url: "/reports"
    },
    {
        name: "Manage Users",
        templateUrl: "/view/users.html",
        url: "/users",
        adminRequired: true
    }
];

加载菜单后,当单击一个菜单元素时,我想获取数据对url属性进行ajax调用,并且获取此数据的模板也将是ajax调用templateUrl财产。

那么,这怎么可以实现呢?基本上我想要的是有一个指令/组件/其他,默认情况下它将是空的,不显示或呈现。但是当我点击菜单中的一个元素时,我要用dataUrl / templateUrl向指令/组件/其他人广播一个事件,它将进行两次ajax调用,一次获取数据,另一次获取数据获取模板,完成后,它将呈现并显示在页面上。

任何方式,或建议做类似的事情将非常感激

顺便说一下,我正在使用Angular 1.5.7

1 个答案:

答案 0 :(得分:1)

你应该使用路由(在我的例子中它是ui-router)来实现这一点 ui-router具有resolve属性,可让您解析控制器依赖关系,然后让它们将它们注入控制器以便使用它们。

这是我做过的一个完整的例子(对于可怜的用户而言):

HTML:

<div ng-app="app">
  <div ng-controller="homeCtrl as vm">
    <menu items="vm.items"></menu>
  </div>
  <div>
    <ui-view></ui-view>
  </div>
</div>

JS:

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

app.controller('gamesCtrl', function(data) {
  this.title = data.title;
}).
controller('reportsCtrl', function(data) {
  this.title = data.title;
}).
controller('usersCtrl', function(data, adminData) {
  this.title = data.title;
  this.removedUsers = adminData.removedUsers;
}).
controller('homeCtrl', function() {
  this.items = [{
    name: 'Manage games',
    state: 'games'
  }, {
    name: 'Weekly Reports',
    state: 'reports'
  }, {
    name: 'Manage Users',
    state: 'users',
    adminRequired: true
  }];
});

app.component('menu', {
  bindings: {
    items: "="
  },
  template: '<div ng-repeat="item in  $ctrl.items"><span ng-click="$ctrl.goToState(item)">{{item.name}}</span></div>',
  controller: function($state) {
    this.goToState = function(item) {
      console.log('redirecting to state:' + item.state);
      $state.go(item.state);
    }
  }
});

app.config(function($stateProvider, $urlRouterProvider) {
  $stateProvider.
  state('games', {
    url: '/games',
    template: '<div><h1>{{vm.title}}</h1></div>', // use templateUrl..
    resolve: {
      data: function($q) {
        return $q.when({
          title: 'games'
        })
      }
    }, // return injectables who return promises and inject them into your ctrl
    controller: 'gamesCtrl as vm'
  }).
  state('reports', {
    url: '/reports',
    template: '<div><h1>{{vm.title}}</h1></div>', // use templateUrl..
    resolve: {
      data: function($q) {
        return $q.when({
          title: 'reports'
        })
      }
    }, // return injectables who return promises and inject them into your ctrl
    controller: 'reportsCtrl as vm'
  }).
  state('users', {
    url: '/users',
    template: '<div><h1>{{vm.title}}</h1><div>Removed Users:</div><div ng-repeat="user in vm.removedUsers">{{user}}</div></div>', // use templateUrl..
    // return injectables who return promises and inject them into your ctrl
    resolve: {
      data: function($q) {
        return $q.when({
          title: 'users'
        })
      },
      adminData: function($q) {
        return $q.when({
          removedUsers: ['user1', 'user2', 'user3']
        })
      }
    },
    controller: 'usersCtrl as vm'
  }).
  state('default', {
    url: '/default',
    template: '<h1>This is the default state</h1>'
  });

  $urlRouterProvider.otherwise('/default');
});

JSFIDDLE

<强>说明

  • 在配置状态时,您应该使用templateUrl而不是模板。
  • 我使用$q.when来证明一个承诺的回归。您可能会使用$http.get\pos来代替。