我从服务器收到一个模型,它是一个(导航)菜单。 所以它有1个根项,带有一系列菜单项。根项目也有标题。 menuitems数组是一个项目数组,包含一个title和一个linkItems数组(具有controller,action,css等属性的对象)。
我的knockout viewmodel中有相同的模型,但是所有的数组和属性都是可观察的数组/字符串/整数。
现在我这样做了
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {Link} from 'react-router'
import {Table, Column} from '../../Layout/components/Table'
import ReactDOM from 'react-dom'
// import ExternalPortal from '../../Sites/components/ExternalPortal'
export const TableName = 'ProjectDashboard'
class MyWindowPortal extends Component {
static propTypes = {
children: PropTypes.node,
closeWindowPortal: PropTypes.func
}
constructor (props) {
super(props)
this.containerEl = document.createElement('div') // STEP 1: create an empty div
this.externalWindow = null
}
componentDidMount () {
// STEP 3: open a new browser window and store a reference to it
this.externalWindow = window.open('', '', 'width=600,height=400')
// STEP 4: append the container <div> (that has props.children appended to it) to the body of the new window
this.externalWindow.document.body.appendChild(this.containerEl)
this.externalWindow.document.title = 'A React portal window'
// copyStyles(document, this.externalWindow.document)
// update the state in the parent component if the user closes the
// new window
this.externalWindow.addEventListener('beforeunload', () => {
this.props.closeWindowPortal()
})
}
componentWillUnmount () {
// This will fire when this.state.showWindowPortal in the parent component becomes false
// So we tidy up by just closing the window
this.externalWindow.close()
}
render () {
// STEP 2: append props.children to the container <div> that isn't mounted anywhere yet
return ReactDOM.createPortal(this.props.children, this.containerEl)
}
}
export default class ProjectTable extends Component {
constructor (props) {
super(props)
this.state={showWindowPortal:false}
this.toggleWindowPortal = this.toggleWindowPortal.bind(this)
this.closeWindowPortal = this.closeWindowPortal.bind(this)
}
static propTypes = {
data: PropTypes.object.isRequired,
loginId: PropTypes.string.isRequired
}
componentDidMount () {
window.addEventListener('beforeunload', () => {
this.closeWindowPortal()
})
}
toggleWindowPortal () {
this.setState({showWindowPortal: !this.state.showWindowPortal})
}
closeWindowPortal () {
this.setState({showWindowPortal: false})
}
render () {
return (
<div>
<div>
<p>This div is just for testing click here to see the portal</p>
{
this.state.showWindowPortal &&
(
<MyWindowPortal closeWindowPortal={this.closeWindowPortal}>
<button
onClick={() => this.closeWindowPortal()}
>
Close
</button>
</MyWindowPortal>
)
}
<button onClick={this.toggleWindowPortal}>
{this.state.showWindowPortal ? 'Close the' : 'Open a'} Portal
</button>
</div>
</div>
)
}
}
我有一个带有可观察数组的菜单,但下面的所有项目都是&#39;或者&#39;降低&#39;在树上是正常的&#39;对象而不是可观察的对象。
我见过vm.menuitems(menuitemsfromserver)
方法,但我无法理解它。
模型是相同的,唯一的区别是一个由可观察(-arrays)和另一个纯javascript对象组成。
答案 0 :(得分:1)
有一个特别针对该案例制作的插件:http://knockoutjs.com/documentation/plugins-mapping.html
从其文档:
// Every time data is received from the server:
ko.mapping.fromJS(data, viewModel);
对象的所有属性都将转换为可观察对象。如果更新将更改该值,则它将更新observable。
将数组转换为可观察数组。如果更新会更改项目数,则会执行相应的添加/删除操作。它还会尝试保持顺序与原始JavaScript数组相同。
在您的情况下,代码看起来像:
ko.mapping.fromJS(menuitemsfromserver, vm.menuitems)
它将迭代所有属性和 menuitemsfromserver 的所有数组,并将它们转换为可观察对象。
最近没有积极维护插件,如下所示:https://github.com/SteveSanderson/knockout.mapping,但为了这个目的,它仍然是一个有用的代码。