【问题标题】:Evaluating an expression from the server with Angular 2使用 Angular 2 评估来自服务器的表达式
【发布时间】:2017-04-28 00:06:50
【问题描述】:

我正在编写一个应用程序,我需要从方法内部传递一个 ngIf 表达式。表达式来自后端服务作为字符串。在 Angular 1 中,我曾经在传递给 ng-if 之前使用插值来评估字符串,然后将其评估为真或假,请看下面的 plunker

更新

Plunker Angular 1.5 https://plnkr.co/edit/ukGlJvBZyqGvvrmjEZJY?p=preview

但是在 Angular 2 中,我不能使用带有 *ngIf 的插值,抛出异常。看看下面的代码。我期望没有一行(Howdy1、Howdy2、Howdy3)出现在 UI 上,因为它传递了相同的表达式。但是只有第一个被隐藏而不是剩下的两个,其中表达式作为字符串变量传递。

我有 Angular 2 和 1.5 的 plunker 代码。如果有人解决了类似的问题,请帮助我。

import {Component, NgModule} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'

@Component({
  selector: 'my-app',
  template: `
    <h1>Angular 2 Systemjs start</h1>
    <div *ngIf="map['a']=='b' || map['b']=='a'">Howdy1</div>
    <div *ngIf="logicAsString">Howdy2</div>
    <div *ngIf="showDiv(logicAsString)">Howdy3</div>
    <p>{{logicAsString}}</p>
  `
})
export class AppComponent {

  logicAsString:string ="map['a']=='b' || map['b']=='a'";

  map = {
    a:'a',
    b:'b'
  }

  public showDiv(logic){
    return logic; 
  }
}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ AppComponent ],
  bootstrap: [ AppComponent ]
})
export class AppModule {}

Plunker Angular 2- https://plnkr.co/edit/YExzpE?p=preview

【问题讨论】:

    标签: angular


    【解决方案1】:

    使用 JavaScript 中的新函数语法,您可以将 showDiv 函数更改为:

    public showDiv (logic) {
       let myfunc = new Function ('map', logic);
       let myresult:boolean = myfunc (this.map);
       return myresult;
    }
    

    您还必须将 logicAsString 更改为:

    logicAsString:string = "if (map['a'] == 'c') return true; return false;"
    

    所以它会将布尔值返回给调用者。这实际上只是包装了您现有的 logicAsString,因此您甚至可以在 showDiv 函数中执行此操作。

    而且这并没有使用很多人不喜欢的 eval。

    希望对你有帮助!

    【讨论】:

    • 我喜欢你的解决方案。似乎它比 eval 更好 :) 如果像我这样对 JavaScript 中的 Function 不太了解的人可以查看此链接 2ality.com/2014/01/eval.html
    【解决方案2】:

    最好的解决方案是将表达式作为原始 HTML 从服务器输出, 那么你可以简单地做:

    <div *ngIf="SERVEROUTPUT"></div> 
    

    或者您将需要使用 JavaScript 原生的 eval function

    【讨论】:

    • 它比我最初解释的要复杂一点。在我的情况下,逻辑来自后端作为字符串。为了模仿我在 plunker 下面创建的情况。您可以看到“Howdy1”没有得到预期的渲染。同样,我期待“Howdy2”和“Howdy3”消失,但事实并非如此。 plnkr.co/edit/YExzpE?p=preview
    • 那个 Plunker 是 Angular 1.5 并且上面有 JavaScript 错误?
    • 我看到了,我错误地使用了 ng-if 而不是 ng-show。 Plunker 已更新。由于 ng-show 在 angular 2 中不可用,我尝试了 [hidden] 和 *ngIf 但两者都不起作用。我发现如果我将 angular 2 plunker 中的 showHide() 方法更改为返回 eval(logic) 而不是简单的逻辑,它就可以工作。但是对使用 eval 持怀疑态度。有什么想法吗?更新代码plnkr.co/edit/KxVor9?p=preview
    • 你可以简单地去
      Howdy2
      。那会正确评估它吗?如果您需要从服务器输出字符串,则需要执行以下操作:
      where SERVEROUTPUT is map['a'] == 'a'
    • 在 plunker 中,我试图模仿与您解释的完全相同的内容。 logicAsString 是那里的 SERVEROUTPUT。问题是,当您直接在 html 中编写表达式时,它可以工作,但是当您将它作为字符串变量传递时,它不会。字符串变量总是被评估为真,字符串中的表达式不会被评估。
    【解决方案3】:

    JavaScript 中的 eval 函数将用于执行您在上面创建的 logicAsString。

    <div *ngIf="eval(logicAsString)">Howdy2</div>
    <div *ngIf="eval(showDiv(logicAsString))">Howdy3</div>
    

    Eval 是一个很多人不喜欢但至少有效的函数。 JavaScript 有一种新的 Function 语法,我曾使用过它,但找不到让它在此处正常工作的神奇语法,您可能会发现它更容易接受。

    如果我可以使新功能正常工作,我也会发布该答案。

    此解决方案允许您根据需要构建 logicAsString,并允许在运行时对其进行修改。这是解决方案的一个优点,但从安全角度来看也是一个缺点。

    【讨论】:

    • 是的 eval 可以解决问题,但我对使用 eval 犹豫不决,出于某些显而易见的原因,你知道 :) 我会对没有 eval 的其他解决方案感兴趣。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-25
    • 2015-11-05
    • 2017-02-15
    • 2012-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多