GVKun编程网logo

为什么在使用* ngIf时,角色模板局部变量在模板中不可用

23

想了解为什么在使用*ngIf时,角色模板局部变量在模板中不可用的新动态吗?本文将为您提供详细的信息,此外,我们还将为您介绍关于12、在模板中定义变量、angularjs–为什么变量只有在ng-incl

想了解为什么在使用* ngIf时,角色模板局部变量在模板中不可用的新动态吗?本文将为您提供详细的信息,此外,我们还将为您介绍关于12、在模板中定义变量、angularjs – 为什么变量只有在ng-include中的onLoad传递时才能在模板中访问?、Angular中为什么不要在模板中调用方法、Angular模板局部变量的新知识。

本文目录一览:

为什么在使用* ngIf时,角色模板局部变量在模板中不可用

为什么在使用* ngIf时,角色模板局部变量在模板中不可用

使用* ngIf时,第1部分“#test”未定义

当引用可以隐藏/“销毁”的输入(因为使用了* ngIf并且某些元素被销毁),由angular2的主题标签语法#(#test在下面的示例中)创建的局部变量不起作用,即使元素存在于页面中。

代码是:

@Component({
    selector: 'my-app',template: `<h1>My First Angular 2 App</h1>
    <button (click)="focusOther(test)">test</button>
    <input #test *ngIf="boolValue" >
    `
})
export class AppComponent { 

  private isVisible = false;

  focusOther(testElement){
    this.isVisible = true;
    alert(testElement);
    testElement.focus();
  }

}

警报显示“undefined”,因为没有任何内容被传递给该功能。

是否有解决方案使其工作?
我的目标是集中一个将被创建的元素。

Mark Rajcok提供的解决方案:使用一个使用elementRef并在元素上调用.focus()的afterViewInit指令。

看到这个plunker的第1部分的工作版本:
http://plnkr.co/edit/JmBBHMo1hXLe4jrbpVdv?p=preview

第2部分如何在初始创建后重新聚焦该元素

一旦这个“创建后聚焦”的问题被修复,我需要一种方法来重新聚焦()一个组件,如“test.focus()”(其中#test是输入的局部变量名,但不能像以前演示过的那样使用)。

Mark Rajcok提供了多种解决方案

对于焦点问题的解决方案,您可以创建一个属性指令focusMe:
import {Component,Directive,ElementRef} from 'angular2/core';
@Directive({
  selector: '[focusMe]'
})
export class FocusDirective {
  constructor(private el: ElementRef) {}
  ngAfterViewInit() {
    this.el.nativeElement.focus();
  }
}
@Component({
    selector: 'my-app',directives: [FocusDirective],template: `<h1>My First Angular 2 App</h1>
      <button (click)="toggle()">toggle</button>
      <input focusMe *ngIf="isVisible">
    `
})
export class AppComponent { 
  constructor() { console.clear(); }
  private isVisible = false;
  toggle() {
    this.isVisible = !this.isVisible;
  }
}

Plunker

更新1:添加重新聚焦功能的解决方案:

import {Component,ElementRef,Input} from 'angular2/core';

@Directive({
  selector: '[focusMe]'
})
export class FocusMe {
    @Input('focusMe') hasFocus: boolean;
    constructor(private elementRef: ElementRef) {}
    ngAfterViewInit() {
      this.elementRef.nativeElement.focus();
    }
    ngOnChanges(changes) {
      //console.log(changes);
      if(changes.hasFocus && changes.hasFocus.currentValue === true) {
        this.elementRef.nativeElement.focus();
      }
    }
}
@Component({
    selector: 'my-app',template: `<h1>My First Angular 2 App</h1>
    <button (click)="showinput()">Make it visible</button>
    <input *ngIf="inputIsVisible" [focusMe]="inputHasFocus">
    <button (click)="focusinput()" *ngIf="inputIsVisible">Focus it</button>
    `,directives:[FocusMe]
})
export class AppComponent {
  private inputIsVisible = false;
  private inputHasFocus = false;
  constructor() { console.clear(); }
  showinput() {
    this.inputIsVisible = true;
  }
  focusinput() {
    this.inputHasFocus = true;
    setTimeout(() => this.inputHasFocus = false,50);
  }
}

Plunker

使用setTimeout()将focus属性重置为false的替代方法是在FocusDirective上创建一个事件/输出属性,并在调用focus()时发出一个事件。然后AppComponent将监听该事件并重置focus属性。

更新2:这是使用ViewChild添加重点焦点功能的替代/更好的方式。我们不需要以这种方式跟踪焦点状态,也不需要在FocusMe指令上输入属性。

import {Component,Input,ViewChild} from 'angular2/core';

@Directive({
  selector: '[focusMe]'
})
export class FocusMe {
    constructor(private elementRef: ElementRef) {}
    ngAfterViewInit() {
      // set focus when element first appears
      this.setFocus();
    }
    setFocus() {
      this.elementRef.nativeElement.focus();
    }
}
@Component({
    selector: 'my-app',template: `<h1>My First Angular 2 App</h1>
    <button (click)="showinput()">Make it visible</button>
    <input *ngIf="inputIsVisible" focusMe>
    <button (click)="focusinput()" *ngIf="inputIsVisible">Focus it</button>
    `,directives:[FocusMe]
})
export class AppComponent {
  @ViewChild(FocusMe) child;
  private inputIsVisible = false;
  constructor() { console.clear(); }
  showinput() {
    this.inputIsVisible = true;
  }
  focusinput() {
    this.child.setFocus();
  }
}

Plunker

更新3:这是另一个不需要使用ViewChild的指令的替代方法,但是我们通过一个本地模板变量而不是一个属性指令来访问该子进程(感谢@alexpods为the tip):

import {Component,ViewChild,ngzone} from 'angular2/core';

@Component({
    selector: 'my-app',template: `<h1>Focus test</h1>
    <button (click)="showinput()">Make it visible</button>
    <input #input1 *ngIf="input1IsVisible">
    <button (click)="focusInput1()" *ngIf="input1IsVisible">Focus it</button>
    `,})
export class AppComponent {
  @ViewChild('input1') input1ElementRef;
  private input1IsVisible = false;
  constructor(private _ngzone: ngzone) { console.clear(); }
  showinput() {
    this.input1IsVisible = true;
    // Give ngIf a chance to render the <input>.
    // Then set the focus,but do this outside the Angualar zone to be efficient.
    // There is no need to run change detection after setTimeout() runs,// since we're only focusing an element.
    this._ngzone.runOutsideAngular(() => { 
      setTimeout(() => this.focusInput1(),0);
   });
  }
  setFocus(elementRef) {
    elementRef.nativeElement.focus();
  }
  ngDoCheck() {
    // if you remove the ngzone stuff above,you'll see
    // this log 3 times instead of 1 when you click the
    // "Make it visible" button.
    console.log('doCheck');
  }
  focusInput1() {
    this.setFocus(this.input1ElementRef);
  }
}

Plunker

更新4:我更新了更新3中的代码以使用ngzone,以便在setTimeout()完成后,我们不会导致Angular的更改检测算法运行。 (有关更改检测的更多信息,请参阅this answer)。

更新5:我更新了上面的代码,使用Renderer来使web worker安全。不要直接在nativeElement上访问focus()。

focusInput1() {
  this._renderer.invokeElementMethod(
    this.input1ElementRef.nativeElement,'focus',[]);
}

我从这个问题中学到很多东西。

12、在模板中定义变量

12、在模板中定义变量

模板文件 index.html

<!DOCTYPE html>
<html lang="en">
	<head>
		<Meta charset="UTF-8" />
		<title>Title</title>
	</head>
	<body>
    {# set定义变量 #}
 	   {% set telephone ='1388888888' %}
 	   {% set nav = [('index.html', 'index'),('product.html', 'product')] %}
 	   {{ telephone }}<br />
 	   {{ nav}} <br />

    {# with 定义变量 #}
 	   {% with pass = 60 %}
 		 {{ pass }}
 	   {% endwith %}
	</body>
</html>

定义主程序

from flask import Flask,render_template
app = Flask(__name__)

@app.route('/')
def hello_world():
    return render_template('index.html')
    
if __name__ == '__main__':
    app.run(debug=True)

参考资料

https://weread.qq.com/web/reader/0a932660718ac6bc0a9702e

angularjs – 为什么变量只有在ng-include中的onLoad传递时才能在模板中访问?

angularjs – 为什么变量只有在ng-include中的onLoad传递时才能在模板中访问?

我对角度范围如何工作感到困惑!

我使用ng-init和onLoad将两个变量传递给一个模板.这两个变量值都是从模板访问的,但是有一个控制器我已经绑定到该模板.我在想为什么两个变量都从模板打印它的值,但是从控制器访问时打印undefined(onLoad varibale).

小提琴说明我的问题jsFiddle

我所理解的是,当我们使用ng-init传递变量时,它会在当前范围内创建该变量,但是对于由onLoad传递的变量是什么?

请告诉我它是如何工作的.

谢谢.

解决方法

第二个控制器都可以访问这两个变量.

但是(看起来像)第二个控制器是在评估onload表达式之前创建的.话虽这么说,如果你想访问范围变量,你可以通过监视(你可能想要使用监视而不是使用范围变量的初始值,无论如何 – 如果你的变量是一个承诺的结果怎么办? ?).

这是一个示例,显示您可以从第二个控制器访问负载:

http://jsfiddle.net/rDP2t/3/

Angular中为什么不要在模板中调用方法

Angular中为什么不要在模板中调用方法

本篇文章给大家介绍一下angular中不在模板(template)里面调用方法的原因,以及解决方法,希望对大家有所帮助!

Angular中为什么不要在模板中调用方法

在运行 ng generate component 命令后创建angular组件的时候,默认情况下会生成四个文件:

  • 一个组件文件 .component.ts
  • 一个模板文件 .component.html
  • 一个 CSS 文件, .component.css
  • 测试文件 .component.spec.ts

【相关教程推荐:《angular教程》】

模板,就是你的HTML代码,需要避免在里面调用非事件类的方法。举个例子

<!--html 模板-->
<p>
  translate Name: {{ originName }}
</p>
<p>
  translate Name: {{ getTranslatedName(&#39;你好&#39;) }}
</p>
<button (click)="onClick()">Click Me!</button>
登录后复制
// 组件文件
import { Component } from &#39;@angular/core&#39;;

@Component({
  selector: &#39;my-app&#39;,
  templateUrl: &#39;./app.component.html&#39;,
  styleUrls: [&#39;./app.component.css&#39;],
})
export class AppComponent {
  originName = &#39;你好&#39;;

  getTranslatedName(name: string): string {
    console.log(&#39;getTranslatedName called for&#39;, name);
    return &#39;hello world!&#39;;
  }

  onClick() {
    console.log(&#39;Button clicked!&#39;);
  }
}
登录后复制

1.png

我们在模板里面直接调用了getTranslatedName方法,很方便的显示了该方法的返回值 hello world。 看起来没什么问题,但如果我们去检查console会发现这个方法不止调用了一次。

2.png

并且在我们点击按钮的时候,即便没想更改originName,还会继续调用这个方法。

3.png

原因与angular的变化检测机制有关。正常来说我们希望,当一个值发生改变的时候才去重新渲染对应的模块,但angular并没有办法去检测一个函数的返回值是否发生变化,所以只能在每一次检测变化的时候去执行一次这个函数,这也是为什么点击按钮时,即便没有对originName进行更改却还是执行了getTranslatedName

当我们绑定的不是点击事件,而是其他更容易触发的事件,例如 mouseenter, mouseleave, mousemove等该函数可能会被无意义的调用成百上千次,这可能会带来不小的资源浪费而导致性能问题。

一个小Demo:https://stackblitz.com/edit/angular-ivy-4bahvo?file=src/app/app.component.html

大多数情况下,我们总能找到替代方案,例如在onInit赋值

import { Component, OnInit } from &#39;@angular/core&#39;;

@Component({
  selector: &#39;my-app&#39;,
  templateUrl: &#39;./app.component.html&#39;,
  styleUrls: [&#39;./app.component.css&#39;],
})
export class AppComponent implements OnInit {
  originName = &#39;你好&#39;;
  TranslatedName: string;

  ngOnInit(): void {
    this.TranslatedName = this.getTranslatedName(this.originName)
  }
  getTranslatedName(name: string): string {
    console.count(&#39;getTranslatedName&#39;);
    return &#39;hello world!&#39;;
  }

  onClick() {
    console.log(&#39;Button clicked!&#39;);
  }
}
登录后复制

或者使用pipe,避免文章过长,就不详述了。

更多编程相关知识,请访问:编程视频!!

以上就是Angular中为什么不要在模板中调用方法的详细内容,更多请关注php中文网其它相关文章!

Angular模板局部变量

Angular模板局部变量

 模板局部变量是模板中对DOM元素或指令(包括组件)的引用,可以使用在当前元素及其同级、子元素中。在Angular组件交互中通过局部变量获取子组件引用就是对组件的引用,这里主要说一下DOM元素局部变量和表单指令局部变量。

DOM元素局部变量

在标签元素中定义DOM元素局部变量,只需要在局部变量名前面加上#号,或是前缀ref-

  <div #good id="good">栗子</div>
  <div ref-good id="good">栗子</div>

它的作用是对当前DOM元素的引用,相当于对document.getElementById("good")对象的引用。定义了DOM元素局部变量后就可以使用该元素的DOM属性了。

表单指令局部变量

表单指令局部变量的使用需要在定义时初始化为特定的(NgForm、NgModel、NgModelGroup)表单指令,最终解析后会被赋值为表单指令实例对象的引用。

就是对应表单指令实例对象的引用(FormControl的引用),作用在于模板中追踪表单状态用于表单的数据校验,不过只能在模板中使用。要想在组件中使用,需要用到ReactiveFormsModule里面的指令。

<form #good="ngForm">
  ...
  <input type="..." ... #goodman="ngModel" />
</form>

NgForm和NgModel指令包含五个表示状态的属性

状态               boolean
valid            表单值是否有效 
pristine         表单值是否未改变
dirty            表单值是否已改变
touched          表单是否已被访问过
untouched        表单是否未被访问过

具体使用方法很多,比如

<buttom type="submit" [disable]="!good.valid">提交</buttom>

 

关于为什么在使用* ngIf时,角色模板局部变量在模板中不可用的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于12、在模板中定义变量、angularjs – 为什么变量只有在ng-include中的onLoad传递时才能在模板中访问?、Angular中为什么不要在模板中调用方法、Angular模板局部变量等相关知识的信息别忘了在本站进行查找喔。

本文标签: