2016-09-26 48 views
2

我正在使用Angular ui-select来创建“搜索和选择组件”。当用户键入搜索字段时,它会立即将项目列表筛选为自由文本过滤器。此外,用户可以从下拉菜单中选择选项,这些选项在过滤器中用作精确的搜索词(例如按类别过滤)。如何将回调传递给扩展现有指令的Angular指令?

我创建了一条额外的指令,该指令扩展了<ui-select>以访问该范围内的$select.search值。该变量包含用户键入的自由文本。我的问题是,我怎么能传递给父控制器?

理想情况下,我想类似如下:

<ui-select 
    my-ui-select 
    on-search-changed="searchChanged(newValue, oldValue)" 
    multiple 
    ng-model="ctrl.myModel"> 
    <!-- ... --> 
</ui-select> 

我的自定义指令将调用on-search-changed回调与自由文本值。问题是我无法为my-ui-select指令定义范围,因为它会与ui-select范围发生冲突。

如何将回调方法传递给我的自定义指令,同时仍然能够访问ui-select范围?或者有更好的方法来实现我所追求的目标?我建立了a Plunker based on the ui-select examples。我已经定义了myUiSelect指令,它使用console.log来输出搜索条件。我想要的是从那里拨打DemoCtrl.searchChanged方法。

回答

0

在您的自定义指令中,您的call on-search-changed回调函数可以发出带有$ emit的事件。 文档约$ emit

通过作用域层级通知 注册$ rootScope.Scope听众向上将事件调度名。

所以,你可以这样做:

$scope.$emit("mySelectEventThing", "Hey this is the value I want to emit"); 

而且在你的父母范围/控制器,你可以监听事件:

$scope.$on("mySelectEventThing", function(event, theValue) { 
    alert(theValue); // alert with 'Hey this is the value I want to emit' 
}); 

$ emit广播向上到父作用域。 $ broadcast向下发送给所有子范围。如果您有很多范围,$广播的性能会更高一点。你可能不需要这个。

发送事件是Angular将数据正确传递到另一个作用域的唯一方法。

您也可以通过使用$ scope。$ parent来达到父范围,但这是非常不好的练习,因为您无法确保达到预期范围。

0

我认为你应该改变你的方法,而不是在你的指令中扩展ui选择,你应该把它包装在yoru指令中,并将你的控制器中的函数传递给指令。

代码指令

app.directive('myUiSelect', function() { 
    return { 
    templateUrl:'myUiSelect.html', 
    scope:{ 
     onSearchChanged:'=', 
     selectedItem:'=', 
     items:'=' 
    }, 
    link: function(scope, element, attrs, $select) { 
    scope.selectedItemModel = { 
     selectedItem:[] 

    } 
    scope.onSelectCallback = function(item, selectedItems){ 

    scope.onSearchChanged(scope.selectedItemModel.selectedItem, item) 

    } 
    } 
}; 
}) 

HTML部分(myUiSelect.html)

<ui-select multiple 
     ng-model="selectedItemModel.selectedItem" 
     theme="bootstrap" 
     ng-disabled="ctrl.disabled" 
     sortable="true" 
     on-select="onSelectCallback($item, $model)" 
     close-on-select="false" 
     style="width: 800px;"> 
<ui-select-match placeholder="Select person...">{{$item.name}} &lt;{{$item.email}}&gt;</ui-select-match> 
<ui-select-choices repeat="person in items | propsFilter: {name: $select.search, age: $select.search}"> 
    <div ng-bind-html="person.name | highlight: $select.search"></div> 
    <small> 
    email: {{person.email}} 
    age: <span ng-bind-html="''+person.age | highlight: $select.search"></span> 
    </small> 
</ui-select-choices> 
</ui-select> 

这里是工作Plunker

请让我知道,如果我的这个问题的认识是错误的