【问题标题】:How to evaluate stored expression in AngularJS $scope如何评估 AngularJS $scope 中的存储表达式
【发布时间】:2014-12-25 21:44:56
【问题描述】:

请帮助我解决这个问题。以下是代码。

HTML:

<div ng-controller="ctrl"><a href="{{ link }}">click here</a></div>

JS:

app.controller('ctrl', function($scope) {
  $scope.true_link = "http://google.com";
  $scope.link = "{{ true_link }}";
});

结果:

<div ng-controller="ctrl"><a href="{{ true_link }}">click here</a></div>

期望:

<div ng-controller="ctrl"><a href="http://google.com">click here</a></div>

在 HTML 中将 {{ link }} 替换为 {{ true_link }} 将解决此问题。但我必须使用这种方式。如何再次评估 $scope.link 内容中的表达式?请帮我。谢谢。


更新

看起来像 facebook,我有两个墙页面:用户页面和演员页面。在诸如 changeAvatar()、changeCover()、post() 等业务功能之后,它们具有相同的模板结构和流程(追加、删除元素等)......所以我创建了基于“主页”的指令:

JS

app.directive('homepage', function() {
  return {
    restrict: 'A',
    templateUrl: 'homepage.html',
    controller: 'homepageCtrl'
  };
});

app.controller('homepageCtrl', function($scope) {
  $scope.changeAvatar() = ...;
  $scope.post() = ...;
});

还有两个扩展控制器:

app.controller('userCtrl', function($scope, $http) {
  $http.({...}).success((data){ $scope.username = data.username })

  $scope.menu = [
    {
      title: "foo-user"
      link: "/u/{{ username }}/foo-user"
    }
    {
      title: "bar-user"
      link: "/u/{{ username }}/bar-user"
    }
  ]
});

app.controller('actorCtrl', function($scope) {
  $http.({...}).success((data){ $scope.actorname = data.actorname })

  $scope.menu = [
    {
      title: "foo-actor"
      link: "/u/{{ actorname }}/foo-actor"
    }
    {
      title: "bar-actor"
      link: "/u/{{ actorname }}/bar-actor"
    }
  ]
});

HTML

主页.html

<section>
  <header>
    <ul class="menu">
      <li ng-repeat="_menu in menu">
        <a href="{{ _menu.link }}">
          {{ _menu.title }}
        </a>
      </li>
    </ul>
  </header>
  <main>
    content...
  </main>
</section>

用户页面:

<div homepage ng-controller="userCtrl"></div>

演员页面:

<div homepage ng-controller="actorCtrl"></div>

两页菜单具有相同的 HTML 结构和效果,但项目不同。我想在扩展控制器(userCtrl,actorCtrl)中定义菜单项并通过 ng-repeat 打印它们。问题是评估 $scope.menu.link 内容。


解决方案

我找到了解决方案:使用 $scope.$eval (https://docs.angularjs.org/guide/expression)。

userCtrl 中,$scope.menu[i].link 是动态内容,因为包含username - 从 ajax 调用接收。我可以使用foreach 更新$http.success() 中的$scope.menu[i].link。但我认为使用 $scope.$eval 可以帮助我更轻松地自动更新。

所以,代码是:

JS

app.controller('userCtrl', function($scope, $http) {
  $http.({...}).success((data){ $scope.username = data.username })

  $scope.menu = [
    {
      title: "foo-user"
      link: "'/u/' + username + '/foo-user'"
      show: 'true'
    }
    {
      title: "bar-user"
      link: "'/u/' + {{ username }} + '/bar-user'"
      show: 'username == "lorem"'
    }
  ]
});

HTML

主页.html

<section>
  <header>
    <ul class="menu">
      <li 
        ng-repeat="_menu in menu"
      >
        <a 
          ng-href="{{$parent.$eval(_menu.link)}}"
          ng-show="$parent.$eval(_menu.show)"
        >
          {{_menu.title}}
        </a>
      </li>
    </ul>
  </header>
  <main>
    content...
  </main>
</section>

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    创建一个指令,并使用 $eval 解析表达式:

     app.directive('a', function (){
           return {
                restrict : 'E',
                link: function(scope, element, attr){
                      element.attr('href',scope.$eval(attr.href));
                }
           }
     });
    

    【讨论】:

      【解决方案2】:
      app.controller('ctrl', function($scope) {
         $scope.true_link = "http://google.com";
         $scope.link =  $scope.true_link; // you need a copy of `$scope.true_link` here
      });
      
      <div ng-controller="ctrl"><a ng-href="link">click here</a></div>
      

      【讨论】:

        【解决方案3】:

        $scope.link = "{{ true_link }}"; 这只是一个字符串,没有别的,所以它会这样渲染。

        不要被大括号弄糊涂了。

        您可以使用$compileeval 等使事情复杂化...或者您可以简单地将 true_link 值分配给链接变量。


        更新

        您的 ng-repeat 指令有问题。这个:

        <li ng-repeat="_menu in menu">
            <a href="{{ menu.link }}">{{ menu.title }}</a>
        </li>
        

        应该是这个(注_menu):

        <li ng-repeat="_menu in menu">
            <a href="{{ _menu.link }}">{{ _menu.title }}</a>
        </li>
        

        另外,没有必要在你的控制器中使用模板,所以这个:

        $scope.menu = [
        {
          title: "foo-user"
          link: "/u/{{ username }}/foo-user"
        }
        {
          title: "bar-user"
          link: "/u/{{ username }}/bar-user"
        }
        ] 
        

        可以这样:

        $scope.menu = [
        {
          title: "foo-user"
          link: "/u/" + $scope.username + "/foo-user"
        }
        {
          title: "bar-user"
          link: "/u/" + $scope.username + "/bar-user"
        }
        ] 
        

        【讨论】:

        • 不客气。我认为我的更新中解决了所有问题。
        • 非常感谢 Shomz 花时间解决我的问题。我希望链接具有动态内容。我找到了解决方案:使用 $scope.$eval。我更新了问题中的解决方案。
        • 不客气。是的,我在原始答案中提到了 eval 。但请注意它的负面影响:stackoverflow.com/questions/86513/…
        【解决方案4】:

        为什么要使用 {{link}} 而不是 {{true_link}}?您遇到的“您必须以这种方式使用”的问题到底是什么?如果你能详细解释一下,我们可以想出一个更好的解决方案。

        【讨论】:

        • 我更清楚地更新了我的问题。还有其他办法吗?谢谢。
        猜你喜欢
        • 2019-07-18
        • 2016-07-26
        • 1970-01-01
        • 1970-01-01
        • 2010-09-27
        • 1970-01-01
        • 2021-03-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多