问题描述
我的项目涉及解析Word文档以提取一组令牌,然后允许用户有选择地对这些令牌执行批量操作。由于UI步骤,我需要能够从提取令牌的Run调用后续myRange.select()
和myRange.font.set(...)
。
如果这更适合作为堆栈溢出帖子,我很抱歉,并将在那里重新发布,但据我所知,库似乎与API不匹配。不过,我肯定会弄错的。
预期行为
我希望调用Word.run(ctx => myRange.select())
会导致选择该范围,因为该范围是在上一次运行时添加到context.trackedObjects
的。
当前行为
没有任何反应,甚至控制台也没有错误。
注意将context
对象保留在Chunk
类上并将其用于后续运行的注释代码将在Word Online/Chrome上运行,但不能在Windows或OSX Word中运行
您的环境
- 平台[PC台式机、Mac、iOS、Office Online]:Win11台式机、OSX、Word Online(均为最新版本)
- 主机[Excel、Word、PowerPoint等]:Word
- Office版本号:最新
- 操作系统:OSX/Win11
- 浏览器(如果使用Office Online):Chrome
代码:
import * as React from 'react'
import { Container, ListGroup, ListGroupItem, Button, Label, Input, ButtonGroup, Row } from 'reactstrap'
class Chunk {
range: Word.Range
text: string
// context: Word.RequestContext
constructor(t: string, r: Word.Range, ctx: Word.RequestContext) {
this.range = r
this.text = t
ctx.trackedObjects.add(r)
r.track()
// this.context = ctx
}
async select(ctx: Word.RequestContext) {
console.log('select')
this.range.select('Select')
ctx.sync()
}
}
const getChunks = async () => {
return Word.run(async context => {
let paragraphs = context.document.body.paragraphs.load()
let wordRanges: Array<Word.RangeCollection> = []
await context.sync()
paragraphs.items.forEach(paragraph => {
const ranges = paragraph.getTextRanges([' ', ',', '.', ']', ')'], true)
ranges.load('text')
wordRanges.push(ranges)
})
await context.sync()
let chunks: Chunk[] = []
wordRanges.forEach(ranges => ranges.items.forEach(range => {
chunks.push(new Chunk(range.text, range, context))
}))
await context.sync()
return chunks
})
}
interface ChunkControlProps { chunk: Chunk; onSelect: (e: React.MouseEvent<HTMLElement>) => void }
export const ChunkControl: React.SFC<ChunkControlProps> = ({ chunk, onSelect}) => {
return (
<div style={{marginLeft: '0.5em'}}><a href='#' onClick={onSelect}>{chunk.text}</a></div>
)
}
export class App extends React.Component<{title: string}, {chunks: Chunk[]}> {
constructor(props, context) {
super(props, context)
this.state = { chunks: [] }
}
componentDidMount() { this.click() }
click = async () => {
const chunks = await getChunks()
this.setState(prev => ({ ...prev, chunks: chunks }))
}
onSelectRange(chunk: Chunk) {
return async (e: React.MouseEvent<HTMLElement>) => {
e.preventDefault()
Word.run(ctx => chunk.select(ctx))
}
}
render() {
return (
<Container fluid={true}>
<Button color='primary' size='sm' block className='ms-welcome__action' onClick={this.click}>Find Chunks</Button>
<hr/>
<ListGroup>
{this.state.chunks.map((chunk, idx) => (
<ListGroupItem key={idx}>
<ChunkControl onSelect={this.onSelectRange(chunk)} chunk={chunk}/>
</ListGroupItem>
))}
</ListGroup>
</Container>
)
};
};
可在WordOnline上运行但不能在Windows或OSX上运行的版本:
(来自上面省略的重复代码)
class Chunk {
range: Word.Range
text: string
context: Word.RequestContext
constructor(t: string, r: Word.Range, ctx: Word.RequestContext) {
this.range = r
this.text = t
this.context = ctx
}
async select() {
this.range.select('Select')
ctx.sync()
}
}
const getChunks = async () => {
return Word.run(async context => {
...
})
}
...
export class App extends React.Component<{title: string}, {chunks: Chunk[]}> {
constructor(props, context) {
super(props, context)
this.state = { chunks: [] }
}
componentDidMount() { this.click() }
click = async () => {
const chunks = await getChunks()
this.setState(prev => ({ ...prev, chunks: chunks }))
}
onSelectRange(chunk: Chunk) {
return async (e: React.MouseEvent<HTMLElement>) => {
e.preventDefault()
chunk.select()
}
}
render() {
return (
<Container fluid={true}>
<Button color='primary' size='sm' block className='ms-welcome__action' onClick={this.click}>Find Chunks</Button>
<hr/>
<ListGroup>
{this.state.chunks.map((chunk, idx) => (
<ListGroupItem key={idx}>
<ChunkControl onSelect={this.onSelectRange(chunk)} chunk={chunk}/>
</ListGroupItem>
))}
</ListGroup>
</Container>
)
};
};
推荐答案
就一般模式而言:诀窍是像通常那样执行Word.run
,而不是让它创建一个新的匿名请求上下文,使用某个现有对象的上下文恢复运行。要继续使用现有上下文,只需使用以下函数之一可从Word.run获得的重载;即,接受对象(或对象数组)作为第一个参数,批处理作为第二个参数:
请注意,为了能够跨不同的range.track()以延长其生存期;并且您应该在某个时候使用range.untrack()
将其清除。
本书中可能对您有帮助的相关章节:
至于您对在线和Windows/Mac之间的行为差异的观察--这非常有趣,听起来像是一个应该调查的错误。你介意在https://github.com/OfficeDev/office-js/issues上只为那个特定的方面提交一个错误,并尽可能少地重现吗?(很抱歉让您来回走动,我知道您在https://github.com/OfficeDev/office-js/issues/68已经在那里了;但我想区分一下概念问题,它实际上只是一个问题(和文档问题),与从行为差异中看到的可能的错误)。
最佳!
~Michael
这篇关于似乎不能跨Office JS中对Word.run(Context=>;{...})的调用使用范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!