Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 角度2变化检测在cli中的表现不同&;网页包_Angularjs_Angular_Webpack_Systemjs_Angular Cli - Fatal编程技术网

Angularjs 角度2变化检测在cli中的表现不同&;网页包

Angularjs 角度2变化检测在cli中的表现不同&;网页包,angularjs,angular,webpack,systemjs,angular-cli,Angularjs,Angular,Webpack,Systemjs,Angular Cli,我们的应用程序有一个问题,很难确定。在这一点上,我相对确信angular(或zone,或webpack,或angular cli)中的某个地方有一个bug,但复制应用程序所需的复杂性使得发布bug报告或plunk有点禁止。所以我想我会在这里发帖,希望有人能提供一些处理过类似挑战的见解 我们正在加载的页面包含多个相互作用的组件,但我会尽量保持对问题的描述尽可能简单。OnInit,我们的组件进行异步调用以获取下拉列表的一些数据。当在列表中选择一个项目时,将异步加载第二组选项的数据。选择其中一个时,将

我们的应用程序有一个问题,很难确定。在这一点上,我相对确信angular(或zone,或webpack,或angular cli)中的某个地方有一个bug,但复制应用程序所需的复杂性使得发布bug报告或plunk有点禁止。所以我想我会在这里发帖,希望有人能提供一些处理过类似挑战的见解

我们正在加载的页面包含多个相互作用的组件,但我会尽量保持对问题的描述尽可能简单。OnInit,我们的组件进行异步调用以获取下拉列表的一些数据。当在列表中选择一个项目时,将异步加载第二组选项的数据。选择其中一个时,将异步加载详细信息数据。当data detail observable为detail对象发出新值时,我们将components detail变量设置为新数据,并更新绑定到此变量的视图元素

所述选项可以一次手动选择一个,也可以作为路由参数传入。当由route params提供时,选择会一个接一个地自动处理,触发相同的异步调用序列,最终在视图中显示细节数据

自rc1以来,我们一直在使用TypeScript 1.8从VisualStudio开发和构建,并使用SystemJS作为运行时模块加载器。但我们最近开始准备发布,并决定尝试angular cli来捆绑我们的脚本并为生产构建。angular cli构建利用Web包加载模块

大多数情况下,在cli构建中一切正常,但我们看到调用更改检测的次数减少了。在我上面描述的情况下,这导致更改检测在一系列异步数据调用的中途停止运行,当我们加载应用程序时,我们的选项作为路由参数传入。我们可以在控制台中看到,已经返回了详细数据,但是视图在某一点之后不会更新,即使绑定到模板元素的变量实际上被设置为新值。组件的更改检测器不会再次运行以获取更改。如果我们单击屏幕上的任何位置或执行其他触发更改检测器的操作,视图将立即反映新数据

angular模块和其他依赖项的所有版本都是最新的稳定版本,并且在两个版本之间是相同的。但是VisualStudio/SystemJS构建工作正常(并且似乎更经常地根据ngDoCheck内部的调试语句运行更改检测方式),而angular cli/webpack版本在检测中途的更改时暂停

我已经花了大约两天的时间在小型化的angular和zone脚本中寻找不同之处,但到目前为止,我还不能理解为什么变更检测的行为如此不同。我可以通过在组件代码中使用settimeout和其他黑客来迫使变更检测器运行来绕过这个问题,但我真的很想理解为什么我首先必须这样做。任何人如能提供任何见解,将不胜感激

其他信息:

下面是组件的订阅处理程序中的代码。我认为,仅仅是sub接收到一个新值这一事实本身就会导致变化检测,但由于这不起作用,我还将新数据的处理包装在一个setTimeout中。在处理新数据的方法中,绑定到视图中元素的变量会被更新,我认为这也会触发更改检测,但不会

fundsService.fundDetail$.subscribe(
(updatedDetails) => {
    $log.debug('subscription received new data');
    $log.debug('setting timeout. will handle new data inside timeout');
    setTimeout(() => {
        this.handleNewFundDetail(updatedDetails);
        $log.debug('data set into vars bound to view. shouldn\'t change detection run now?');
    });
},
(error) => {
    $log.error('Error loading fund detail: ' + error.message);
    this.dialogService.error('Error loading fund detail.');
}
)

正如您可以从控制台日志中看到的,VisualStudio中构建的相同代码实际上在这一点之后运行更改检测。事实上,即使没有在超时中包装数据处理方法,它也会这样做

但是,当从angular cli构建运行时,在订阅中接收到新数据后,没有变化检测,setTimeout没有变化检测,模板绑定变量发生变化时也没有变化检测

那么这里到底发生了什么?为什么变化检测不触发

更新:如果我在订阅中的另一个超时内嵌套了一个超时,则会运行更改检测。如果我只是在handleNewDetail之后添加一个超时,或者只在handleNewDetail周围包装超时,则不会检测到更改。但如果我像这样嵌套它,就会突然发生变化检测。当然,这样做是荒谬和武断的,在我们使用angular cli构建应用程序之前,这是不必要的/

service.detail$.subscribe(
(updatedDetails) => {

    setTimeout(() => {
        this.handleNewDetail(updatedDetails);
        setTimeout(() => {
            $log.debug('inception timeout inside a timeout');
            //CHANGE DETECTION ACTUALLY HAPPENS
        },100);
    });
}    

将此作为angular cli团队的一个问题打开,并被要求尝试删除polyfills.ts中的导入,而是通过index.html中的CDN下拉这些脚本,如下所示

<script src="https://unpkg.com/core-js/client/shim.min.js"></script>
<script src="https://unpkg.com/zone.js@0.6.25?main=browser"></script>
<script src="https://unpkg.com/reflect-metadata@0.1.3"></script>

您是否尝试过将这些值放入ngOnChange中,然后查看它是否有效?我的理解是,当组件的实际输入发生更改时,ngOnChange将触发。所讨论的组件没有定义输入,而是异步加载数据,然后订阅更新数据的可观察对象。当可观察对象发出新数据时,我们的订阅将更新绑定到视图中元素的本地变量。虽然我相信如果我们更新组件更改检测的输入,可能会触发,但这不是这个应用程序的结构,它应该按原样工作(并且在我们的开发版本中)
"scripts": [
    "../node_modules/core-js/client/shim.min.js",
    "../node_modules/zone.js/dist/zone.js",
    "../node_modules/reflect-metadata/Reflect.js",
    "common/someOtherScript.js"
  ],