我想在点击 body 标记上的按钮时动态添加CSS类。所以我使用角度的DOCUMENT
对象。这是代码
import { DOCUMENT } from "@angular/platform-browser";
... component code
constructor( @Inject(DOCUMENT) private document: Document) { }
addClass() {
this.document.body.classList.add("any_class");
}
但这显示错误
Metadata collected contains an error that will be reported at runtime: Could not resolve type Document.
[0] {"__symbolic":"error","message":"Could not resolve type","line":50,"character":53,"context":{"typeName":"Document"}}
[0] at \node_modules\@angular\compiler-cli\src\metadata\collector.js:664:27
[0] at Array.forEach (<anonymous>)
[0] at validateMetadata (D:\QPP Workspace\QWC\QWC\node_modules\@angular\compiler-cli\src\metadata\collector.js:652:42)
[0] at MetadataCollector.getMetadata (D:\QPP Workspace\QWC\QWC\node_modules\@angular\compiler-cli\src\metadata\collector.js:507:17)
[0] at LowerMetadataCache.getMetadataAndRequests (ProjectPath\node_modules\@angular\compiler-cli\src\transformers\lower_expressions.js:264:39)
[0] at LowerMetadataCache.ensureMetadataAndRequests (ProjectPath\node_modules\@angular\compiler-cli\src\transformers\lower_expressions.js:209:27)
[0] at LowerMetadataCache.getRequests (ProjectPath\node_modules\@angular\compiler-cli\src\transformers\lower_expressions.js:204:21)
[0] at ProjectPath\node_modules\@angular\compiler-cli\src\transformers\lower_expressions.js:146:36
[0] at ProjectPath\node_modules\typescript\lib\typescript.js:2601:86
[0] at reduceLeft (ProjectPath\node_modules\typescript\lib\typescript.js:2274:30)
error Command failed with exit code 2.
[0] at ChildProcess.exithandler (child_process.js:275:12)
[0] at emitTwo (events.js:126:13)
[0] at ChildProcess.emit (events.js:214:7)
[0] at maybeClose (internal/child_process.js:925:16)
[0] at Process.ChildProcess._handle.onexit (internal/child_process.js:209:5)
问题是什么?我正在使用 angular5 。还有其他方法可以动态添加类吗?
答案 0 :(得分:3)
如果使用类似的方法,则会出现此错误
@Inject(DOCUMENT) document: Document
将tsconfig.json中的编译器设置设置为
"angularCompilerOptions": {
"strictMetadataEmit": true
}
事实证明,角度编译器在计算可注入参数的元数据时不理解类型Document
,即使它理解了注入令牌DOCUMENT
,而Typescript也理解类型{{1 }}。
在此处记录: https://github.com/angular/angular/issues/20351
我使用的解决方法是:
Document
这使用@Injectable({
providedIn: 'root'
})
class MyService {
constructor(@Inject(DOCUMENT) document?: any) {
this._document = document as Document;
}
private _document?: Document;
...
作为注入签名(使角度满意),但为您提供了类内的Typescript类型。
答案 1 :(得分:2)
您可以直接在打字稿中使用//task page code
public class TaskFragment extends android.support.v4.app.Fragment {
private SQLiteDatabase db;
private TaskAdapter taskAdapter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_tasks, null);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//db
TaskDBHelper dbHelper = new TaskDBHelper(TaskFragment.this.getActivity());
db = dbHelper.getWritableDatabase();
RecyclerView recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(TaskFragment.this.getActivity()));
taskAdapter = new TaskAdapter(TaskFragment.this.getActivity(), getAllItems());
recyclerView.setAdapter(taskAdapter);
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
removeItem((long) viewHolder.itemView.getTag());
}
}).attachToRecyclerView(recyclerView);
//
view.findViewById(R.id.add_task_fab).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
openAddTask();
}
});
}
private void removeItem(long id) {
db.delete(TaskContract.TaskEntry.TABLE_NAME,
TaskContract.TaskEntry._ID + "=" + id, null );
taskAdapter.swapCursor(getAllItems());
}
public Cursor getAllItems() {
TaskDBHelper dbHelper = new TaskDBHelper(TaskFragment.this.getActivity());
db = dbHelper.getWritableDatabase();
return db.query(
TaskContract.TaskEntry.TABLE_NAME,
null,
null,
null,
null,
null,
TaskContract.TaskEntry.COLUMN_TIMESTAMP + " DESC"
);
}
public void openAddTask() {
Intent intent = new Intent(TaskFragment.this.getActivity(), AddTask.class);
startActivityForResult(intent, 1);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if(resultCode == Activity.RESULT_OK){
taskAdapter.swapCursor(getAllItems());
}
}
}
}
而无需任何导入。
只需:document
。
答案 2 :(得分:0)
您可以在组件的装饰器之前添加“ / ** @dynamic * /”:
/** @dynamic */
@Component({
如此处https://github.com/angular/angular/issues/20351#issuecomment-344009887和此处https://angular.io/guide/aot-compiler#strictmetadataemit
所述,以抑制错误