【问题标题】:Trying to set TemplateUrl conditionally using a given attribute (Angular)尝试使用给定属性(Angular)有条件地设置 TemplateUrl
【发布时间】:2016-01-23 07:48:09
【问题描述】:

我正在尝试根据控制器中变量的值使用不同的templateUrl,但我无法绑定这些变量。我一直在尝试在链接功能中执行此操作,不确定是否有更简单的方法。首先,这是我的 HTML:

<div po-generic-notification title='errorModal.title' error-list="errorModal.errorList" type="mostRecentError.type" message="mostRecentError.message" error="mostRecentError.message"></div>

这会触发以下指令(在此阶段正在进行一些工作......):

.directive('poGenericNotification', function($compile) {
  var openFuncNameErm = 'openErm';
  return {
    controller: 'ErmModalCtrl',
    restrict: 'EA',
    scope: {
      title: '=',
      errorList: '=',
      type: '=',
      message: '='
    },
    transclude: true,
    link: function(scope, element, attrs) {
      console.log(attrs.type);
      if (attrs.type==="Alert") {
        templateUrl: 'src/alerts/templates/error-alert.html';
        error: attrs.message;
      }
      else if (attrs.type==="Info") {
        templateUrl: 'src/alerts/templates/info-alert.html';
        info: attrs.message;
      }
      error: attrs.message; //temporary
      element.removeAttr('po-generic-notification'); // necessary to avoid infinite compile loop
      var ngClick;
      if (attrs.before) {
        ngClick = attrs.ngClick ? openFuncNameErm + '()' + '; ' + attrs.ngClick : openFuncNameErm + '()';
      }
      else {
        ngClick = attrs.ngClick ? attrs.ngClick + '; ' + openFuncNameErm + '()' : openFuncNameErm + '()';
      }
      element.attr('ng-click', ngClick);
      $compile(element[0])(scope);
    }
  }
})

您可以在我的链接函数中看到我尝试根据attrs.type 的值有条件地设置templateUrlconsole.log 的结果是 mostRecentError.type 而不是来自控制器的值。这是我的控制器:

.controller('ErrorModalCtrl', ['errorHandler', '$scope', function (errorHandler, $scope) {
    $scope.errorModal = {
        title: 'Notification Centre',
        errorList: []
    };
    $scope.mostRecentError = {
      type:'', message: '', timestamp: ''
    };
    $scope.addError = function(type, message) {
        errorHandler.addError(type, message);
        $scope.mostRecentError = errorHandler[0];
    };
    $scope.errorModal.errorList = errorHandler;
}]);

这是正确的方法吗?为什么我的 attrs.type 值是文字,而不是对控制器的引用?

谢谢

【问题讨论】:

  • 属性总是被读取为文字,而不是将它们传递到从父作用域评估它们的作用域

标签: angularjs angularjs-directive binding


【解决方案1】:

你已经设置了范围,所以只需使用它而不是 attrs:

link: function(scope, elem, attrs) {
    if (scope.type === 'Alert') {...}
}

我还建议只传递整个 errorMsg 一次:

scope: { errMsg: '='}

然后在你的 html 中:

<div po-generic-notification title='errorModal.title' error-list="errorModal.errorList" err-msg="mostRecentError"div>

然后在您的链接功能中,您可以像这样访问它们:

scope.errMsg.type;
scope.errMsg.message;
scope.errMsg.error;

【讨论】:

  • 有趣....这使我可以在启动时访问我的 mostRecentError 对象中的值。问题是,这些值会发生变化,我希望这些值随着时间的推移而更新。链接函数是否只编译一次?如果是这样,解决方法是什么?
  • 只要 mostRecentError 对象更改,您的范围值应该更新。确保您正确更改它。
【解决方案2】:

要通过传递的属性获取不同的模板,在指令声明中你可以简单地写:

return {
    scope:{},
    templateUrl: function(element,attrs){
         if (attrs.type==="Alert") {
             return 'src/alerts/templates/error-alert.html';
         else if (attrs.type==="Info") {
             return 'src/alerts/templates/info-alert.html';
         }
    }
    link: function(){
        // ...
    }
};

当您通过attrs 访问属性时,它们只是一组字符串。如果您从独立的作用域(作用域:{})或作用域.$eval()访问它们,则当属性值被评估并转换为值或对父控制器的引用时。

【讨论】:

  • 但是如果像你说的attrs.type 不计算值,你如何访问实际值?我尝试将scope 传递给函数并使用scope.type,但这返回了一个未定义的值。
猜你喜欢
  • 2016-12-02
  • 2017-05-28
  • 1970-01-01
  • 1970-01-01
  • 2022-11-18
  • 2019-03-30
  • 1970-01-01
  • 2019-08-19
  • 1970-01-01
相关资源
最近更新 更多