最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is it a good practice to use Function calls inside {{}} (Curly Brackets)? - Stack Overflow

programmeradmin4浏览0评论

Is it a good practice to use Function calls inside {{}} (Curly Brackets)?

Is there any way to do this? within the component, for example (maybe using ngOnChanges or anything like that...)

Template

<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>

Component

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
        });
    }
}

/

ps. I need to display HTML content in a textarea, that's why I'm doing the html inside the component.

Is it a good practice to use Function calls inside {{}} (Curly Brackets)?

Is there any way to do this? within the component, for example (maybe using ngOnChanges or anything like that...)

Template

<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>

Component

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. I need to display HTML content in a textarea, that's why I'm doing the html inside the component.

Share Improve this question asked Sep 27, 2018 at 2:30 carloscarlos 6631 gold badge7 silver badges15 bronze badges 2
  • I would probably avoid doing it, but if you have to do it in any case do not forget to sanitize it. – arbghl Commented Sep 27, 2018 at 2:34
  • I'd say that the javascript tag is not relevant here (the Typescript tag could) – Pac0 Commented Sep 27, 2018 at 10:11
Add a comment  | 

3 Answers 3

Reset to default 11

The answer for your question is: it depends.

If the execution time of the function is short, that's fine. In case the function includes many complex calculation which take a quite long time to finish, then it might cause a serious problem with the user experience.

This is what the Angular team said in their official document:

Quick execution

Angular executes template expressions after every change detection cycle. Change detection cycles are triggered by many asynchronous activities such as promise resolutions, http results, timer events, keypresses and mouse moves.

Expressions should finish quickly or the user experience may drag, especially on slower devices. Consider caching values when their computation is expensive.

For reference: https://angular.io/guide/template-syntax#quick-execution

Function calls inside handlebars (double curlies) are legit. However, if you console.log in the function you will see it is called often so best to keep it lightweight as possible or memoize it if it is a pure function. See lodash memoize.

If the function has no arguments (or can be rewritten to accept no arguments) then you can use a TypeScript getter instead like so:

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

And now you can just use {{ something }} in the HTML template. Worth placing a console.log here to see if it is called less times than the function equivalent.

Angular has a very convenient feature that allows binding data directly to the result of a method call. By using Angular’s template binding syntax to assign an attribute to a method, the results will be recalculated with every change detection cycle. While this can be convenient, it also adds the results of these calculations to the cost of every change detection cycle. This cost has the potential to greatly impact an application’s responsiveness, for example, when binding to a method is combined with an ngFor. There are generally two approaches for improving performance when this happens: pre-computing the results or implementing the method as a pure pipe.

The most common situation in which an ngFor is combined with a method call is to perform a calculation based on each entry that is displayed. Rather than recomputing the display value on every change detection, there is often opportunity to calculate the additional properties as needed. For example consider the following code:

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

A simple template binding that executes numClasses for each entry in instructorList on every change detection cycle

The backing component class for the template sources its data with no upfront processing. The following implementation defines the method to call from the template

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

In this example, object properties are only recalculated if the list changes. This occurs significantly less often than each change detection cycle, possibly never again. This is the most perform-ant way to handle such situations, but it can sometimes be difficult to achieve.

发布评论

评论列表(0)

  1. 暂无评论