Проблема с наблюдаемыми и событиями в angular 2

#reactjs #angular #rxjs

#reactjs #angular #rxjs

Вопрос:

Может кто-нибудь, пожалуйста, скажите мне, почему это не сработает?

В настоящее время я прохожу курс по angular, и инструктор оставил нас в грязи в отношении обновлений с момента создания курса… Я занимаюсь темой наблюдаемых, и это код, который не работает.

 import {Component, ElementRef} from 'angular2/core'
import {Observable} from 'rxjs/Rx'

import 'rxjs/add/operator/map'

@Component({
    selector: 'my-app',
    template: `
        <input id="search" type="text" class="form-control" placeholder="Search" />
    `
})

export class AppComponent {
    constructor(private _elementRef: ElementRef) {
        var elem = document.querySelector('#search');
        var keyups = Observable.fromEvent(elem, "keyup")
            .map(e => e.target.value)
            .filter(text => text.length >= 3);

        keyups.subscribe(data => console.log(data));
    }
}
  

Это ничего не выведет на консоль и не выдает никаких ошибок.

Что я здесь делаю не так?

****Редактировать****

После извлечения кода моих инструкторов и повторного запуска всего, я убежден, что это проблема с версиями rxjs. В этой версии мне больше не нужно включать:

 import 'rxjs/add/operator/map'
  

И когда я пишу следующий код, он работает и выводится на консоль, как и ожидалось.

 /// <reference path="../typings/tsd.d.ts" />

import {Component} from 'angular2/core';
import {Observable} from 'rxjs/Rx'

@Component({
    selector: 'my-app',
    template: `
        <input id="search" type="text" class="form-control">
    `
})
export class AppComponent {
    constructor(){
        var keyups = Observable.fromEvent($("#search"), "keyup")
            .map(e => e.target.value)
            .filter(text => text.length > 3);

            keyups.subscribe(data => console.log(data));
    }
}
  

Когда я приостанавливаю приложение в отладчике и просматриваю keyups, у него действительно есть элемент.

Также ради любопытства, вот html, который используем я и инструктор.

 <html>

  <head>
    <title>Angular 2 QuickStart</title>
    <link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.css"></style>
    <link rel="stylesheet" href="app/styles.css">
    <style>
        body { padding: 30px; }
    </style>
    <!-- 1. Load libraries -->
    <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script src="node_modules/rxjs/bundles/Rx.js"></script>
    <script src="node_modules/angular2/bundles/angular2.dev.js"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js">   </script>
    <script  src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

    <!-- 2. Configure SystemJS -->
   <script>
      System.config({
        packages: {        
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        }
      });
      System.import('app/boot')
            .then(null, console.error.bind(console));
    </script>

  </head>

  <!-- 3. Display the application -->
  <body>
    <my-app>Loading...</my-app>
  </body>

</html>
  

Комментарии:

1. Попробуйте вставить это ngOnInit . Я предполагаю, что вы отладили это в своем отладчике. Когда вы ставите точку останова в var keyups строке и проверяете getElementById('search") , что вы видите?

2. Предложение: это плохая практика доступа к DOM непосредственно из компонента, возможно, вам следует написать директиву с ElementRef для манипулирования DOM.

3. Я не верю, что проблема с загрузкой, пожалуйста, смотрите Отредактированный пост.

4. @CodeBuster ценю понимание. Я понимаю это, но поскольку это курс angular 2, я просто следовал указаниям инструкторов до этого момента. Я уверен, что это лучшая практика, но для простоты, я думаю, он просто вставил код в компонент. Не уверен. Я обязательно буду помнить об этой передовой практике.

5. классное просто предложение 🙂

Ответ №1:

В вашем коде elem будет равно null .

Я думаю, вам следует переместить свой код в ngAfterViewInit hook. Это как «при загрузке» для компонента.

Смотрите также

Плунжер