【问题标题】:Alternative to $eval Executing Function in Angularjs DirectiveAngularjs 指令中 $eval 执行函数的替代方案
【发布时间】:2015-05-01 07:38:25
【问题描述】:

我有一个自定义元素指令(显示用户的图片和名称),它可以采用许多不同的配置属性。 uc-on-hover 属性可以采用一个函数来确定当用户将鼠标悬停在 DOM 元素上时要显示的元素。目前,该函数的逻辑位于 $rootScope (在角度服务中定义)。指令逻辑执行$eval(attr['ucOnHover']) 以在$rootScope 上执行函数。虽然这种模式暂时运作良好,但我担心它太复杂并且 $rootScope 会变得笨拙。无论如何我可以改变解决方案设计,同时仍然注意指令和服务的关注点分离并制定灵活的解决方案?

我在视图上下文中的自定义元素指令:

<user-card locator="{{ Item.Author }}" uc-on-hover="$root.namespace.displayFloatingContainer()"></user-card>

定义$rootScope.namespace.displayFloatingContainer()的服务:

.service('uiElementService', ['$rootScope', function ($rootScope) {

    $rootScope.ngRestForm.displayFloatingContainer = function (code) {

            try {
                console.log('rootscope.uielementservice hit with code: ' + code);
                return true;
            } catch (err) {
            }
        return false;
        };       
}])
 .run(function (uiElementService) {
     console.log('uiElementService: Start');
 });

指令通过以下方式调用 $rootScope 上的函数:

$scope.$eval(attrs["ucOnHover"]);

对此设计的任何帮助将不胜感激。

【问题讨论】:

  • $scope.$apply(attrs['ucOnHover']); ?
  • user-card 指令是否使用隔离作用域?
  • 是的,user-card 指令使用隔离范围。
  • 我尝试了@Baszz 建议并收到错误:[$rootScope:inprog] $digest 已经在进行中,仅使用 $scope.$eval(attrs['ucOnHover']) 时不会发生这种情况

标签: javascript angularjs angularjs-directive rootscope


【解决方案1】:

您可以使用 $parse,并在指令范围内运行该函数。

https://docs.angularjs.org/api/ng/service/$parse

您的服务可以注入到您正在执行的函数被定义的任何地方,并从您正在运行的函数中调用。

这是一个 uc-on-hover 指令的准系统框架,它触发作为参数数组的一部分传入的函数

(function() {

angular
  .module('yourModuleName')
  .directive('ucOnHover', ucOnHover);

ucOnHover.$inject = ['$parse'];

function ucOnHover($parse) {

var directive = {
  restrict: 'A',
  link: link
}

return directive;

function link(scope, element, attrs) {

  var args = attrs['ucOnHover'].split(' ');

  var hoverFunctions = [];

  angular.forEach(args, function(hoverFunc) {
      hoverFunctions.push($parse(hoverFunc));
  });

  element.on('hover', function(event) {
    event.preventDefault();
    event.stopPropagation();
    scope.$apply(function() {
      angular.forEach(hoverFunctions, function(hoverFn) {
         hoverFn(scope);
       });
    });
  });


}


}

})();

这是模板中使用的相同指令

<user-card locator="{{ Item.Author }}" uc-on-hover="hoverFunction()"                                         ></user-card>

【讨论】:

  • 感谢您的回复。现在我已经在服务中定义了功能。我使用该服务作为组织在 $rootScope 上定义的相关功能的一种方式。 (示例签名:$rootScope.ngRestForm.displayFloatingContainer)。这种组织方式的替代方法是将服务外部的 displayFloatingContainer() 等函数提取到可以从视图访问的全局对象中。必须有一种更好的方法来组织我想做的事情,同时让指令与 displayFloatingContainer() 中的逻辑分离。
  • 作为旁注,很高兴知道我可以将提供程序注入任何函数。尽管它的使用频率是另一个讨论。
猜你喜欢
  • 2013-05-22
  • 1970-01-01
  • 2013-04-10
  • 1970-01-01
  • 1970-01-01
  • 2015-08-25
  • 1970-01-01
  • 1970-01-01
  • 2015-07-31
相关资源
最近更新 更多