从指令调用控制器函数不会更新范围

Calling controller function from directive does not update scope

我使用服务和 $resource 创建了一个指令来搜索 REST API 并将结果传递给控制器​​。代码如下所示:

app.controller('productsCtrl', ['$scope', function ($scope) {
    var self = this;
    self.selection;

    self.searched = function (selected) {
        self.selection = selected;
    };
}]);

app.service('productsService', ['productsResource', function (productsResource) {
    var self = this;

    self.findProducts = function (search) {
        return productsResource.query({
            sku: search
        });
    };
}]);

app.factory('productsResource', ['$resource', function ($resource) {
    return $resource('products/:sku', {
        id: '@sku'
    });
}]);

app.directive('productSearch', ['productsService', function (productsService) {
    return {
        restrict: 'E',
        scope: {
            productSelected: '&'
        },
        templateUrl: '/products/product_search.html',
        link: function (scope) {
            scope.findProducts = function (search) {
                scope.searchResults = productsService.findProducts(search);
            };
            scope.selectResult = function (selected) {
                scope.selection = selected;
                scope.showResults = false;
            };
        }
    };
}]);

相关的 HTML 行是:

<div ng-show='products.selection'>
    {{products.selection.name}}  //does not update
</div>

来自指令模板:

<div ng-click="productSelected({selected: selection})"></div>

问题是当指令调用控制器方法时我的模型没有更新(它将显示上次搜索的结果)。这对我来说有点意义,因为那里没有调用 "angular" 函数。但我应该如何让它发挥作用。我试过 $scope.$apply() 但会引发错误。

作为附带问题。我这样做的方式对吗?这是 angular 方式吗?特别是在指令中使用服务并将指令中的内容传递给控制器​​?

编辑: 这是整个 HTML 文件(使用 controllerAs):

<div>
    <product-search product-selected='products.searched(selected)'></product-search>
    <div ng-show='products.selection'>
        {{products.selection.name}}
    </div>
</div>

我认为您缺少指令的回调。您可能需要添加

scope.productSelected({selected: selection})

在指令的 scope.selectResult 函数内。完整代码如下所示

 scope.selectResult = function (selected) {
     scope.selection = selected;
     scope.showResults = false;
     scope.productSelected({selected: selected}); // add this
 };