在{{}}(Curly Brackets)中使用Function调用是一种好习惯吗?

时间:2018-09-27 02:30:51

标签: javascript angular

在{{}}(弯括号)内使用Function调用是一种好习惯吗?

有没有办法做到这一点?例如在组件中(可能使用ngOnChanges或类似的东西...)

模板

<div class="container">
    {{ bootstrap() }}
    {{ validate() }}  
    <textarea class="form-control">{{ fullHtml }}</textarea>
    <button (click)="copy()" class="btn btn-primary">Click to Copy HTML</button>
    <textarea class="form-control">{{ validator }}</textarea>
    <button (click)="copy()" class="btn btn-warning">Click to Copy Validate</button>

    <button class="btn btn-danger" (click)="add()">Add page and input</button>
</div>

组件

class HomeComponent {
    fullHtml = "";
    validator = "";
    pages = [{
        "name": "Page 1"
    },{
        "name": "Page 2"
    }];

    inputs = [{
        "name": "input_1",
        "required": true
    },{
        "name": "input_2",
        "required": false
    }];

    public bootstrap() {
        this.fullHtml = this.pages.map((page, pageNumber) => {
            return '<div class="row">' +
                page.name +
                '</div>'
        }).join('')
    }

    public validate(){
        this.validator = this.inputs.map((input, i) => {
            return '"' + input.name + '" => [' + (input.required? 'required': 'nullable') + '],\n';
        }).join('')
    }

    public copy(){
        alert("under construction");
    }

    public add(){
        this.pages.push({
            name: "page 3"
        });
        this.inputs.push({
            "name": "input_3",
            "required": true
        });
    }
}

https://jsfiddle.net/1hk7knwq/10283/

ps。我需要在文本区域中显示HTML内容,这就是为什么我要在组件内部执行html。

3 个答案:

答案 0 :(得分:10)

您的问题的答案是:这取决于。

如果函数的执行时间很短,那很好。如果该功能包含许多复杂的计算,而这些计算需要很长时间才能完成,则可能会导致严重的用户体验问题。

这是Angular团队在其正式文件中所说的:

  

快速执行

     

每一次更改检测后,Angular都会执行模板表达式   周期。变化检测周期由许多异步事件触发   活动,例如承诺解决方案,http结果,计时器事件,   按键和鼠标移动。

     

表达式应该很快完成,否则用户体验可能会拖延,   特别是在速度较慢的设备上。当它们的值考虑缓存值   计算很昂贵。

以供参考:https://angular.io/guide/template-syntax#quick-execution

答案 1 :(得分:5)

车把内的功能调用(双曲柄)是合法的。但是,如果您在函数中console.log,您会经常看到它被调用,因此最好使其保持轻量级,或者如果它是纯函数则记住它。参见lodash memoize

如果该函数没有参数(或者可以重写为不接受任何参数),则可以这样使用TypeScript getter:

get something() {
  // do some code here
  // return 5
}

现在您可以在HTML模板中使用{{ something }}。值得在此处放置console.log来查看它的调用次数是否少于等效函数的调用次数。

答案 2 :(得分:3)

Angular具有非常方便的功能,该功能允许将数据直接绑定到方法调用的结果。通过使用Angular的模板绑定语法为方法分配属性,将在每个更改检测周期重新计算结果。尽管这可能很方便,但也会将这些计算的结果添加到每个更改检测周期的成本中。例如,将绑定方法与ngFor结合使用时,此成本可能会极大地影响应用程序的响应能力。发生这种情况时,通常有两种方法可以提高性能:预先计算结果或将方法实现为纯管道。

将ngFor与方法调用结合在一起的最常见情况是根据显示的每个条目执行计算。与其在每次更改检测时都重新计算显示值,不如经常有机会根据需要计算其他属性。例如,考虑以下代码:

<ul>
  <li *ngFor="let instractor of instractorList">
    <span>Upccoming classes {{numClasses(instractor)}}</span>
  </li>
</ul>

一个简单的模板绑定,它在每个更改检测周期内为教师列表中的每个条目执行numClasses

模板的后备组件类无需预先处理即可获取其数据。以下实现定义了从模板调用的方法

<ul>
  <li *ngFor="let instractor of instractorList">
    <span>Upccoming classes {{instractor.numClasses}}</span>
  </li>
</ul>

在此示例中,仅在列表更改时才重新计算对象属性。与每个更改检测周期相比,这种情况发生的频率明显降低,可能不再发生。这是处理此类情况的最有效方法,但有时可能很难实现。