如何在评估后检查表达式是否具有值

时间:2014-10-08 02:36:22

标签: angularjs angularjs-directive angularjs-scope

假设我有以下模板:

"foo['x'] = '{{ myVar }}';"

是否有一种角度方式检查是否根据我当前的范围进行评估会给myVar一些值?我有一系列这样的小模板,我只想在值很简单时将它们包含在文档中。我希望$ interpo,$ parse或$ eval可能派上用场。我肯定知道$ interpolate是没用的。那两个呢?也许至少可以获得指定值/表达式的名称?

修改

我不够具体。我试图实现的是,如果例如针对当前范围评估的模板'{{ myVar }}'将返回空字符串或范围变量的值(如果存在),则提前检查。这个案例非常具体 - 当遍历一组短模板时,我想知道模板是否会以空字符串形式返回,如果没有,则只包含在我的最终html中。

2 个答案:

答案 0 :(得分:0)

我不确定你想要达到的目标,但如果你想检查当前范围内myVar是否真实,你可以:

{{myVar ? "aw yiss" : "nope"}}

评估" aw yiss"如果myVar是真的,那么" nope"否则。

答案 1 :(得分:0)

我最终得到了一个修改过的$ interpolate提供程序,但也许有人知道更短的解决方案:

app.provider('customInterpolateProvider', [

  function $InterpolateProvider() {

    var startSymbol = '{{';
    var endSymbol = '}}';

    this.startSymbol = function(value){
      if (value) {
        startSymbol = value;
        return this;
      } else {
        return startSymbol;
      }
    };

    this.endSymbol = function(value){
      if (value) {
        endSymbol = value;
        return this;
      } else {
        return endSymbol;
      }
    };

    this.$get = ['$parse', '$sce', function($parse, $sce) {
      var startSymbolLength = startSymbol.length,
          endSymbolLength = endSymbol.length;

      function $interpolate(text, mustHaveExpression, trustedContext, allOrNothing) {
        allOrNothing = !!allOrNothing;
        var startIndex,
            endIndex,
            index = 0,
            expressions = [],
            parseFns = [],
            textLength = text.length,
            exp;

        var getValue = function (value) {
          return trustedContext ?
            $sce.getTrusted(trustedContext, value) :
            $sce.valueOf(value);
        };

        var stringify = function (value) {
          if (value == null) {
            return '';
          }
          switch (typeof value) {
            case 'string':
              break;
            case 'number': 
              value = '' + value;
              break;
            default: 
              value = angular.toJson(value);
          }

          return value;
        };

        var parseStringifyInterceptor = function(value) {
          try {
            return stringify(getValue(value));
          } catch(err) {
            console.err(err.toString());
          }
        };

        while(index < textLength) {
          if ( ((startIndex = text.indexOf(startSymbol, index)) !== -1) &&
               ((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) !== -1) ) {
            exp = text.substring(startIndex + startSymbolLength, endIndex);
            expressions.push(exp);
            parseFns.push($parse(exp, parseStringifyInterceptor));
            index = endIndex + endSymbolLength;
          } else {
            break;
          }
        }

        if (!expressions.length && !text.contains(startSymbol) && !text.contains(endSymbol)) {
          expressions.push(text);
        }

        if (!mustHaveExpression) {
          var compute = function(values) {
            for(var i = 0, ii = expressions.length; i < ii; i++) {
              if (allOrNothing && angular.isUndefined(values[i])) {
                return;
              }
              expressions[i] = values[i];
            }
            return expressions.join('');
          };

          return angular.extend(function interpolationFn(context) {
              var i = 0;
              var ii = expressions.length;
              var values = new Array(ii);

              try {
                if (ii && !parseFns.length) {
                  return expressions[0];
                } else {
                  for (; i < ii; i++) {
                    values[i] = parseFns[i](context);
                  }
                  return compute(values);
                }
              } catch(err) {
                console.err(err.toString());
              }

            }, {
            exp: text,
            expressions: expressions,
            $$watchDelegate: function (scope, listener, objectEquality) {
              var lastValue;
              return scope.$watchGroup(parseFns, function interpolateFnWatcher(values, oldValues) {
                var currValue = compute(values);
                if (angular.isFunction(listener)) {
                  listener.call(this, currValue, values !== oldValues ? lastValue : currValue, scope);
                }
                lastValue = currValue;
              }, objectEquality);
            }
          });
        }
      }

      return $interpolate;
    }];
  }
]);

下面的行被添加了,因为在某些情况下我的短模板中有一个预定义的文本,我总是想渲染它:

        if (!expressions.length && !text.contains(startSymbol) && !text.contains(endSymbol)) {
          expressions.push(text);
        }

                if (ii && !parseFns.length) {
                  return expressions[0];
                } else {