在以异步方式填充范围时,应如何将数据传递到指令中

时间:2014-08-01 13:20:40

标签: angularjs asynchronous coffeescript angularjs-directive

我有一个控制器,可以异步填充一些数据。该指令使用该数据。

不幸的是,该指令不显示数据。如果我删除超时(这是模拟异步过程),那么事情就可以了。

我想知道最好的解决方案是什么。我非常肯定这是一种常见的情况 - 我以错误的方式处理事情。有没有办法延迟指令#34; loading"直到填充范围中的数据。

HTML:

html
  head
    link(
  href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css",rel="stylesheet",type="text/css")  
    title Hello World
  body(ng-app="app")
    .container

      .well.
        How should data be passed into a directive when a scope is populated asyncronysly

      div(ng-controller="StoogeCtrl")

       .panel.panel-default
          .panel-heading
            | All 
          .panel-body
            ul
              li(ng-repeat="stooge in stooges") {{stooge.name}}

        .panel.panel-default
          .panel-heading
            | Noe Moe
          .panel-body
            div(filter-stooge except="Moe" stooges="stooges")

的JavaScript(CoffeeScript的):

app = angular.module 'app', []

app.controller 'StoogeCtrl', ($scope, $q, $timeout)->
  stooges = [
    {name: "Moe"}
    {name: "Larry"}
    {name: "Curly"}
  ]

  getPromise = ()->
    dfd = $q.defer()
    dfd.resolve(bars)
    dfd.promise

  $timeout ()->
    $scope.stooges = stooges




app.directive 'filterStooge', ()->
  scope:
    stooges: '='
    except: '@'
  template: "<ul )><li ng-repeat='stooge in filtered'>{{stooge.name}}</li></ul>"
  link: (scope)->
    filtered = []
    for stooge in scope.stooges
      filtered.push stooge if stooge.name != scope.except
    scope.filtered = filtered

基于ExpertSystem(下面)的回答。我这样做了:

app = angular.module 'app', []

app.controller 'StoogeCtrl', ($scope, $q, $timeout)->
  stooges = [
    {name: "Moe"}
    {name: "Larry"}
    {name: "Curly"}
  ]

  getPromise = ()->
    dfd = $q.defer()
    dfd.resolve(bars)
    dfd.promise

  $timeout ()->
    $scope.stooges = stooges
    $scope.done = true
  ,
  3000




app.directive 'filterStooge', ()->
  scope:
    stooges: '='
    except: '@'
    done: '='
  template: "<ul><li ng-repeat='stooge in filtered'>{{stooge.name}}</li></ul>"
  link: (scope)->    
    scope.$watch 'done', (newVal, oldVal)->
      if newVal
        filtered = []
        for stooge in scope.stooges
          filtered.push stooge if stooge.name != scope.except
        scope.filtered = filtered

1 个答案:

答案 0 :(得分:1)

数据未显示,因为您显示了已过滤的数据,并且在创建filtered时,$scope.stooges中没有数据(因此您排序过滤并且空数组,这会产生结果当然是一个空数组。)

您有以下选择:

  • $watch超过$scope.stooges,并在更改后重新构建filtered

  • 在视图中使用过滤(这可能是更好的做法)。要么创建自己的过滤器(如果需要高级过滤功能),要么使用内置的filter过滤器。

例如:

app.directive('filterStooge', function () {
    return {
        scope: {
            stooges: '=',
            except:  '@'
        },
        template:
            '<ul>' +
            '    <li ng-repeat="stooge in stooges | filter:filterSpec">' +
            '        {{stooge.name}}' +
            '    </li>' +
            '</ul>',
        link: function filterStoogePostLink(scope, elem) {
            // If `except` is specified, exclude items by name.
            // If `except` is not specified, show all items.
            scope.filterSpec = scope.except ?
                {name: '!' + scope.except} : 
                '';
        }
    };
});

另请参阅此 short demo


<子> 顺便说一句,您在ngRepeat <ul>元素的位置(这将导致多个<ul>。) 我假设你想要ngRepeat <li>元素。