使用Angular 2从服务器计算表达式

使用Angular 2从服务器计算表达式,angular,Angular,我正在编写一个应用程序,需要从方法内部传递一个ngIf表达式。表达式作为字符串来自后端服务。在Angular 1中,在传递给ng之前,我使用插值来计算字符串,如果ng被计算为true或false,请看下面的plunker 已更新 普朗克角1.5 但在Angular 2中,我不能使用带*ngIf的插值,抛出异常。请看下面的代码。我希望UI上没有一行(Howdy1、Howdy2、Howdy3)传递相同的表达式。但只有第一个表达式是隐藏的,而剩下的两个表达式是作为字符串变量传递的 我有Angular

我正在编写一个应用程序,需要从方法内部传递一个ngIf表达式。表达式作为字符串来自后端服务。在Angular 1中,在传递给ng之前,我使用插值来计算字符串,如果ng被计算为true或false,请看下面的plunker

已更新

普朗克角1.5

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

我有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 {}
从'@angular/core'导入{Component,NgModule}
从“@angular/platform browser”导入{BrowserModule}
@组成部分({
选择器:“我的应用程序”,
模板:`
角度2系统启动
Howdy1
Howdy2
Howdy3
{{logicAsString}}

` }) 导出类AppComponent{ logicAsString:string=“map['a']=='b'| | map['b']=='a'; 地图={ a:‘a’, b:‘b’ } 公共节目组(逻辑){ 返回逻辑; } } @NGD模块({ 导入:[BrowserModule], 声明:[AppComponent], 引导:[AppComponent] }) 导出类AppModule{}
扑通角2-

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

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


或者,您需要使用javascript自带的。javascript中的eval函数将用于执行上面创建的logicAsString

<div *ngIf="eval(logicAsString)">Howdy2</div>
<div *ngIf="eval(showDiv(logicAsString))">Howdy3</div>
Howdy2
Howdy3
Eval是一个很多人都不喜欢的功能,但至少可以工作。JavaScript有一个我使用过的新函数语法,但在这里找不到让它工作的神奇语法,您可能会发现它更容易接受

如果我能让新函数正常工作,我也会发布这个答案


此解决方案允许您按照自己的意愿构建LogicaString,并允许在运行时对其进行修改。这是解决方案的优点,但从安全角度来看也是缺点。

使用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,这是很多人不喜欢的


希望有帮助

这比我最初解释的要复杂一点。在我的例子中,逻辑作为字符串来自后端。模仿我在普朗克下面创造的情况。您可以看到“Howdy1”未获得预期的渲染效果。同样地,我期待着“Howdy2”和“Howdy3”消失,但事实并非如此。plnkr.co/edit/YExzpE?p=preview该Plunker是Angular 1.5,上面有JavaScript错误?我看到了,我错误地使用了ng if而不是ng show。Plunker已更新。由于angular 2中没有ng show,我尝试了[hidden]和*ngIf,但两者都不起作用。我发现如果我将angular 2 Plunk中的showHide()方法更改为返回eval(logic),而不是简单的逻辑,那么它就可以工作。但是使用eval有点怀疑。有什么想法吗?更新的代码,你可以简单地去Howdy2。这将正确评估它吗?如果需要从服务器输出字符串,则需要执行以下操作:其中SERVEROUTPUT是map['a']=='a',在我尝试模拟的plunker中,与您解释的完全相同。logicAsString是那里的服务器输出。问题是,当您直接在html中编写表达式时,它可以工作,但当您将其作为字符串变量传递时,它就不能工作。字符串变量的计算结果始终为true,字符串中的表达式不会得到计算结果。是的,eval可以做到这一点,但我不太愿意使用eval,原因很明显:)我会对没有eval的其他解决方案感兴趣。我喜欢你的解决方案。似乎它比eval:)好得多,如果像我这样对javascript中的函数不太了解的人可以看看这个链接