从外部将值传递给Angular应用程序

Daw*_*ski 2 javascript model-view-controller javascript-objects typescript angular

我正在考虑将基于MVC的网站的前端分成几个组件,并且正在考虑为此目的使用Angular(例如,创建以后可以包含在视图中的购物车应用程序)。

问题是我需要向该应用程序传递几个变量,我想知道如何安全,专业地进行操作。我在想类似的东西:

  1. 我要去 ng build --prod --aot
  2. 我将所有脚本注入了自己的视野
  3. 我注入传递给我的应用程序查看的变量

...和“代码”代表我的想法:

控制器:

public function viewAction()
{
    $this->view->addCss('angular/app/styles.css'); // adds styles for cart app 
    $this->view->addJS('angular/app/scripts.js');  // adds scripts for cart app
    $this->view->setJSVariable('idCustomer', 555); // sets global var idCustomer
}
Run Code Online (Sandbox Code Playgroud)

视图:

<!-- bunch of HTML for view ... -->
<script>
    // CartApp would be an angular app.
    CartApp.use([
        idCustomer
    ]);
</script>
Run Code Online (Sandbox Code Playgroud)

所以我的问题是...是否有可能(并且将是一个很好的解决方案)将CartAppas作为对象,然后执行一些use设置/传递数据的功能(如上述示例)?(比方说一些全球提供的服务/组件或其他任何东西)。还是有其他方法可以做到这一点?就像从window对象中从应用程序内部获取变量一样?(因为它们仍将绑定到窗口)。谢谢。

Sco*_*ner 7

所以我建议使用输入绑定...之前在AngularJS中已经做过,但是很惊讶地发现尚不支持在根组件上使用输入绑定。您可能会很高兴阅读这个大问题: https //github.com/angular/angular/issues/1858

我看到的最好的帖子是Rob Wormald的,其中有一些建议:

  • 对于第一个问题,如果您真的想从根目录中获取数据,可以通过 https://plnkr.co/edit/nOQuXE8hMkhakDNCNR9u?p=preview-请注意,这不是输入(因为外面没有角度上下文)进行输入...)-它是一个简单的字符串属性,您需要自己解析。
  • 不过,理想情况下,您应该按照@robtown的建议进行操作,并实际上以javascript形式传递数据,而不是将其作为DOM字符串传递并自己进行检索/解析(尽管有人明确警告过,但从来没有真正支持角度的情况) -反对在angular1中使用ng-init来完成此操作)- 有关如何执行此操作的简单示例,请参见https://plnkr.co/edit/PoSd07IBvYm1EzeA2yJR?p=preview

因此,我看到的2个不错的选择是:

  1. 将普通的HTML属性添加到根组件:

    <app-root appData='important stuff'></app-root>
    
    Run Code Online (Sandbox Code Playgroud)

    并用于ElementRef获取它们:

    @Component({
      selector: 'app-root'
    })
    export class AppComponent {
      constructor(el: ElementRef) {
        console.log(el.nativeElement.getAttribute('appData'));
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    如果仅处理字符串或配置标志,则可能效果最好。如果要传递JSON,则需要手动解析。

  2. 让服务器将数据呈现为JavaScript并将其导入您的应用程序:

    让服务器在启动Angular之前将这样的内容呈现给已加载的脚本标签或JS文件:

    window.APP_DATA = { ids: [1, 2, 3] }
    
    Run Code Online (Sandbox Code Playgroud)

    使用提供程序告诉您的NgModule:

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    
    import { AppComponent } from './app.component';
    
    @NgModule({
      providers: [{ provide: 'AppData', useValue: (<any> window).APP_DATA }],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    
    Run Code Online (Sandbox Code Playgroud)

    然后将其用作普通的Angular服务:

    import {Component, Inject} from '@angular/core';
    
    @Component({
      selector: 'app-root'
    })
    export class AppComponent {
      constructor(@Inject('AppData') appData) {
        console.log(appData.ids);
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)