如何从另一个类调用reloaddata()?

时间:2017-07-08 22:37:04

标签: swift macos delegates nstableview

我有两个类NSViewController,其中包含NSTableViewNSPageController,可用于将数据添加到表格视图中。如何从reloadData()致电NSPageController以更新NSViewController的表格视图?

更新

我已经尝试用委托来解决这个问题了,我已经在Objective-C中完成了这个,但是我很快就感到完全迷失了。

我的PageController需要通知ViewController,必须更新tableView。所以我将这段代码添加到了我的PageController

protocol PageControllerDelegate {
    func updateTableView()
}

weak var delegate: PageControllerDelegate?

对于保存表视图的ViewController,我添加了以下行:

class ViewController: NSViewController, PageControllerDelegate {
...

func updateTableView() {
        self.tableView.reloadData()
}

Xcode给了我以下错误:

  • '弱'可能只适用于类和类绑定协议类型,而不适用于PageControllerDelegate'
  • 财产'代表'使用类型' PageControllerDelegate?'无法覆盖类型为' NSPageControllerDelegate的属性?' (又名'可选')

2 个答案:

答案 0 :(得分:2)

我只能给你一个通用答案。

首先,您需要一个视图控制器的联系人。与<template lang="pug"> .col-sm-12 h2 Add new Task hr .form-group textarea.form-control(v-model="task.taskContent") .form-group button.btn.btn-primary(@click="createNewTask") Add Task </template> <script> export default { data() { return { task: { taskContent: '' } }; }, methods: { createNewTask() { if (this.task.taskContent.length > 0) { // Sending data to the server this.$http.post('https://vue-taskmanager.firebaseio.com/task.json', this.task) .then(response => { console.log(response); // Adding the new task to the main template list this.$emit('taskWasCreated', this.task); // Resetting textarea content this.task.taskContent = ''; }, error => { console.log(error); }); } else { alert("Sorry you can't create an empty task"); } } } } </script> 或您定义的内容(协议)类似。

示例,当您使用表视图控制器时:

<template lang="pug">           
    .container
        .row
            app-newtask(@taskWasCreated="addTask")
            app-taskswrapper(:tasks="tasksArr")
            app-footer

</template>


<script>
import { EventBus } from './main.js';
import UserRegistration from './components/user/UserRegistration.vue';
import TasksWrapper from './components/TasksWrapper.vue';
import NewTask from './components/NewTask.vue';
import Footer from './components/Footer.vue';
export default {
    data() {
        return {
            tasksArr: [
                'Just something to see'
            ]
        };
    },
    methods: {
        addTask(task) {
            this.tasksArr.push(task)
        }
    },
    // Listening on Events from Task.vue 
    created() {
        // Delete task from array
        EventBus.$on('taskWasDeleted', (taskIndex) => {
            this.tasksArr.splice(taskIndex, 1);
            // Delete task from db
            this.$http.delete('https://vue-taskmanager.firebaseio.com/task.json', this.task)
                .then(response => {
                        console.log(response);
                    }, error => {
                        console.log(error);
                    });
        });
        // Fetch tasks from db
        this.$http.get('https://vue-taskmanager.firebaseio.com/task.json')
            .then(response => {
                return response.json();
            })
            .then(task => {
                const resultsArray = [];
                for (let key in task) {
                    resultsArray.push(task[key]);
                }
                this.tasksArr = resultsArray;
            });      
    },
    components: {
        'app-taskswrapper': TasksWrapper,
        'app-newtask': NewTask,
        'app-footer': Footer,
        'app-userregistration': UserRegistration
    }

}
</script>

例如,当您使用带有合同的视图控制器时:

联系人:

amp-iframe

符合合同的视图控制器:

NSTableViewController

你的重装数据电话:

(viewController as? NSTableViewController)?.tableView.reloadData()

希望它有所帮助。

答案 1 :(得分:0)

一种简单的方法,取决于你的控制层次结构 - 如果你的NSViewControllers持有你的控制器,那么给我们的控制器类一个weak var delegate: NSViewControllerDelegate,并定义一个`protocol

NSViewControllerDelegate: AnyObject {
   func controllerShouldUpdateTableView(_ controller: NSController)
}

让您的NSViewController符合此协议,然后确保在控制器上设置委托。只需在需要重新加载表时调用此函数。