【问题标题】:Angular 1.5 Component: passing a functionAngular 1.5 组件:传递函数
【发布时间】:2016-08-21 10:12:33
【问题描述】:

是否可以将函数传递给组件并在传递参数的组件内部调用此函数?

例子:

帖子列表

<post-list posts="blog.posts"
           loading="blog.loadingPosts"
           get-post-url="blog.getPostUrl" 
           is-user-authenticate="blog.user">
</post-list>

getPostUrl 是一个函数(在容器控制器内):

const getPostUrl = (postId) => {
    const protocol = $location.protocol();
    const host = $location.host();
    const port = $location.port();

    return protocol + "://" + host + "" + (port !== 80 ? ":" + port : "") + "/blog/post/" + postId;
};

帖子列表:组件

const PostList = {
  "bindings": {
    "posts": "<",
    "loading": "<",
    "getPostUrl": "&", //Function getPostUrl
    "isUserAuthenticate": "<"
  },
  "template": `<div>
                <div class="col-md-9 text-center" data-ng-if="$ctrl.loading">
                  <i class="fa fa-spinner fa-spin fa-2x"></i>
                </div>

                <div class="col-md-9 posts" data-ng-if="!$ctrl.loading">
                  <div data-ng-repeat="post in $ctrl.posts">
                    <post creation-date="{{post.creationDate}}"
                          content="{{post.content}}"
                          post-url="{{$ctrl.getPostUrl(post.creationDate)}}"
                          is-user-authenticate="$ctrl.user">
                    </post>
                  </div>
                </div>
              </div>`,
   "transclude": false
};

 angular
  .module("blog")
  .component("postList", PostList);

在这一行:

post-url="{{$ctrl.getPostUrl(post.creationDate)}}"我想调用传递参数的函数,这个函数返回一个字符串

post 组件(不是 PostList)中,postUrl 是一个字符串属性@

但是...不起作用!

angular.js:13550 错误:[$interpolate:interr] 无法插值:{{$ctrl.getPostUrl(post.creationDate)}} TypeError:无法使用“in”运算符在 1459329888892 中搜索“博客” Error Link

有可能吗?以及如何?

非常感谢!

【问题讨论】:

  • 对于&amp; 绑定,您不需要{{ }} - 请参阅文档的这一部分,了解如何实现您想要做的事情的一个很好的例子:docs.angularjs.org/guide/…
  • 但是这个函数的返回是一个字符串...post-url是一个字符串。我想调用返回这个字符串的函数
  • 我现在改了...但是现在出现这个错误:Cannot use 'in' operator to search for 'blog'

标签: javascript angularjs components


【解决方案1】:

您可以将函数传递给组件,但您必须将函数参数定义为对象,并将正确的参数名称作为其键。 示例:

<post-list posts="blog.posts"
           loading="blog.loadingPosts"
           get-post-url="blog.getPostUrl(postId)" 
           is-user-authenticate="blog.user">
</post-list>

const PostList = {
 "bindings": {
  "posts": "<",
  "loading": "<",
  "getPostUrl": "&", //Function getPostUrl
  "isUserAuthenticate": "<"
 },
 "template": `<post creation-date="{{post.creationDate}}"
                      content="{{post.content}}"
                      post-url="{{$ctrl.getPostUrl({postId:post.creationDate})}}">
                </post>

【讨论】:

  • 这应该是公认的解决方案,因为它是正确的函数绑定。谢谢你的提示。我不知道内部组件必须将参数作为命名对象传回。
【解决方案2】:

如果你想从组件内部调用函数并让它返回一个值,那么你需要双向绑定:

"bindings": {
  "posts": "<",
  "loading": "<",
  "getPostUrl": "=", // <-- two-way binding
  "isUserAuthenticate": "<"
},

但是,这可能不是一个好主意。考虑将数据传递给组件,而不是让组件从外部请求数据。这将使隔离组件变得更好。

【讨论】:

    【解决方案3】:

    要将值返回给绑定函数,您必须将其作为对象字面量传递。
    self.selected({id: '42', firstname: 'Douglas', lastname: '亚当斯});

    angular.module('webapp').component('myComponent', {
        templateUrl: 'myComponent.html',
    
        bindings: {
            selected: '&'
        },
        controller: function () {
            var self = this;
    
            self.someEvent= function(){
                self.selected({id: '42', firstname: 'Douglas', lastname: 'Adams'});
            };
        }
    });
    

    之后,您可以通过其属性访问对象字面量值。
    id,名字,姓氏。
    您还可以将其他参数传递给函数。 (我的变量)

    <div>
        <span ng-init="myVariable='Universe'">
        <my-component selected="myFunction(id, firstname, lastname, myVariable)"></my-component>
    </div>
    
    
    $scope.myFunction = function(id, firstname, lastname, myVariable){
        console.log(id, firstname, lastname, myVariable);    
    }
    

    【讨论】:

      【解决方案4】:

      根据 Todd Motto 的标准,不建议使用 '=' 而是尝试使用 '&' 将方法从父组件传递到子组件,并且在子组件中调用该方法将在父组件中触发。举个例子吧。

      父组件的模板(HTML):

      <child take-me-to-school="$ctrl.searchBikeKeyAndStart>
      

      子组件的控制器:

      public someFunction = () => {
        this.takeMeToSchool();
      }
      

      一旦从子组件的控制器调用该函数,那么映射到父组件的函数就会被触发。

      父组件的控制器(HTML):

      public searchBikeKeyAndStart = () => {
        .....
      }
      

      当你想将参数传递给同一个函数时

      父组件的模板(HTML):

      <child take-me-to-school="$ctrl.searchBikeKeyAndStart(**key**)>
      

      子组件的控制器:

      public someFunction = () => {
        this.takeMeToSchool({key: parameterValue});
      }
      

      一旦从子组件的控制器调用该函数,那么映射到父组件的函数就会被触发。

      父组件的控制器(HTML):

      public searchBikeKeyAndStart = (**key**) => {
        console.log(**key**) //will print the param passed
      }
      

      【讨论】:

        猜你喜欢
        • 2016-08-31
        • 2017-03-05
        • 1970-01-01
        • 1970-01-01
        • 2016-02-23
        • 2017-04-15
        • 2017-07-14
        • 2017-03-18
        • 2017-10-10
        相关资源
        最近更新 更多