在组件中从可观察对象设置变量

huangapple go评论64阅读模式
英文:

Setting a variable in the component from an observable

问题

我尝试将组件中的变量绑定到subscribe()函数中的可观察对象的内容。未注释的行运行正常,而已注释的行在编译时会抛出错误“类型'void'不可分配给类型'string'”。

换句话说,这个赋值 this.str = data 会在程序中出现问题。我怀疑这可能是因为在运行时某些时刻data为null,我已经用 if (data) {...} 添加了检查,但仍然无法编译通过。我看到有人以这种方式在组件中绑定变量(因此这应该是一种有效的解决方法),但不明白为什么在这里不允许。

以下是这个示例的完整代码,包括一个带有selectors.ts、reducer.ts和actions.ts的单个component.ts:

组件.ts

export class AppComponent implements OnInit{
    constructor(private _store: Store) {}
    strSub: Subscription;
    str: string;
    numChanged: number;
    observable: Observable<string>;

    ngOnInit() {
        this.strSub = this._store.select(selectStr).subscribe((data) => console.log(data));
        //this.strSub = this._store.select(selectStr).subscribe((data) => {this.str = data});
        // this.observable = this._store.select(selectStr)
    }
}

Selectors.ts

export const myTopLevelSelector = createFeatureSelector<fromReducer.State>(fromReducer.featureKey);

export const selectStr = createSelector(myTopLevelSelector, (state) => {state.str});

Reducer.ts

export const featureKey = 'myFeatureKey';

export interface State {
    str: string,
    numChanged: number
}

export const initialState: State = {
    str: "initialState",
    numChanged: 0
}

const myReducer = createReducer(
    initialState,
    on(myAction1, (state, action) => ({
        ...state,
        str: action.str,
        numChanged: state.numChanged + 1
    }))
)    

export function reducer(state: State | undefined, action: Action) {
    return myReducer(state, action);
}

Actions.ts

export const myAction1 = createAction('ACTION1', props<{str: string, numChanged: number}>());

export const myActionSuccess = createAction('ACTIONSUCCESS');

HTML文件是一个普通的一行代码:<p>{{this.str}}</p>

我看了这个帖子(以及它包含的链接):https://stackoverflow.com/questions/39118301/cannot-get-this-of-component-inside-subscribe-function,问题在格式上有些类似,但根本区别在于我不是试图记录;我试图分配,而分配无法正常工作,而记录可以。

英文:

I am trying to bind a variable in a component to the content from an observable in a subscribe() function with an anonymous function:

ngOnInit() {
    this.strSub = this._store.select(selectStr).subscribe((data) =&gt; console.log(data));
    //this.strSub = this._store.select(selectStr).subscribe((data) =&gt; {this.str = data});
}

The uncommented line runs fine while the commented line throws an error on compilation Type &#39;void&#39; is not assignable to type &#39;string&#39;..

In other words, this assignment this.str = data somehow breaks the program. I suspect this may be due to data being null at some point during run-time, and I added a check with if (data) {...} but it still failed to compile.

I have seen people bind variables in components this way (so it should be a valid way to approach this problem), but don't understand why this isn't allowed here.

Below is the full code for this example which consists of a single component.ts with a selectors.ts, reducer.ts and actions.ts:

Component.ts

export class AppComponent implements OnInit{
    constructor(private _store: Store) {}
    strSub: Subscription;
    str: string;
    numChanged: number;
    observable: Observable&lt;string&gt;;

ngOnInit() {
    this.strSub = this._store.select(selectStr).subscribe((data) =&gt; console.log(data));
    //this.strSub = this._store.select(selectStr).subscribe((data) =&gt; {this.str = data});
    // this.observable = this._store.select(selectStr)
}
}

Selectors.ts

export const myTopLevelSelector = createFeatureSelector&lt;fromReducer.State&gt;(fromReducer.featureKey);

export const selectStr = createSelector(myTopLevelSelector, (state) =&gt; {state.str});

Reducer.ts

export const featureKey = &#39;myFeatureKey&#39;;

export interface State {
    str: string,
    numChanged: number
}

export const initialState: State = {
    str: &quot;initialState&quot;,
    numChanged: 0
}

const myReducer = createReducer(
    initialState,
    on(myAction1, (state, action) =&gt; ({
        ...state,
        str: action.str,
        numChanged: state.numChanged + 1
    }))
)    

export function reducer(state: State | undefined, action: Action) {
    return myReducer(state, action);
}

Actions.ts

export const myAction1 = createAction(&#39;ACTION1&#39;, props&lt;{str: string, numChanged: number}&gt;());

export const myActionSuccess = createAction(&#39;ACTIONSUCCESS&#39;);

The HTML file is an unremarkable one-liner:
&lt;p&gt;{{this.str}}&lt;/p&gt;

I looked at this thread (and the links it contains): https://stackoverflow.com/questions/39118301/cannot-get-this-of-component-inside-subscribe-function, and the problem is somewhat similar in format, but a fundamental difference is that I'm not trying to log; I'm trying to assign, and the assignment doesn't work while the logging works.

答案1

得分: 1

我认为你遇到的问题在于你的选择器。

如果有括号,请将箭头函数中的括号去掉,然后需要在其中添加return

没有括号:

export const selectStr = createSelector(myTopLevelSelector, (state) =&gt; state.str);

有括号:

export const selectStr = createSelector(myTopLevelSelector, (state) =&gt; { return state.str })

希望对你有帮助!

英文:

I think that the problem that you are having is in your selector.

Remove the brackets from the arrow funtion if you have them you will need to add the return into it.

Without brackets

export const selectStr = createSelector(myTopLevelSelector, (state) =&gt; state.str);

With brackets

export const selectStr = createSelector(myTopLevelSelector, (state) =&gt; { return state.str })

Hope it helps you!

huangapple
  • 本文由 发表于 2023年4月4日 06:10:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75924111.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定